zoukankan      html  css  js  c++  java
  • Unity3D学习笔记(九):摄像机

    3D数学复习

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    public class w07d1 : MonoBehaviour {
        public Quaternion result1;
        public Quaternion result2;
        public Quaternion result3;
        // 什么是单位四元数?   
        // [0, 0, 0, 1]        表示无旋转
        // [n.x * sin<theta/2>, n.y * sin<theta/2>, n.z * sin<theta/2>, cos<theta/2>]   绕y轴旋转0度    [0, 0, 0, 1]    绕y轴旋转360度  [0, 0, 0, -1]
        // 什么是标准四元数?
        // 模长为1的四元数
        // 模长 = Mathf.Sqrt(x*x + y*y + z*z * w*w)
        // 什么是共轭四元数?
        // 虚数部分取负
        // 四元数 * 共轭四元数 = 单位四元数
        // 什么是四元数的逆?
        // q^-1 = q^* / |q|     如果q是标准四元数    q^-1 = q^*
        // 如果一个 四元数 * 向量 = 向量 (模长一样,方向不一样,相当于旋转一个向量)
        void Start () {
            // 绕 (1, 1, 0)轴 旋转45度
            result1 = Quaternion.AngleAxis(45, new Vector3(1, 1, 0));
            // 绕 (2, 2, 0)轴 旋转45度
            result2 = Quaternion.AngleAxis(45, new Vector3(2, 2, 0));        // 对轴 标准化
            Quaternion ge = new Quaternion(-result1.x, -result1.y, -result1.z, result1.w);
            result3 = result1 * ge;
            Quaternion q = Quaternion.AngleAxis(45, Vector3.up);
            Vector3 v = new Vector3(1, 0, 1);
            Debug.DrawLine(Vector3.zero, v, Color.green, 1000);
            v = q * v;
            Debug.DrawLine(Vector3.zero, v, Color.red, 1000);
        }
    }

    RotateAround

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    public class MyRotateAroundTest : MonoBehaviour {
        public Transform target;
        public float rotSpeed = 1;
        void Start () {
                  
           }
           
           void Update () {
            MyRotateAround(target.position, target.up, rotSpeed * Time.deltaTime);
                  
           }
        void MyRotateAround(Vector3 pos, Vector3 axis, float angle)
        {
            Quaternion q = Quaternion.AngleAxis(angle, axis);
            Vector3 dir = transform.position - pos;
            Vector3 projectV = (Vector3.Dot(axis, dir) / axis.magnitude) * axis.normalized;
            Vector3 n = dir - projectV;
            Vector3 newN = q * n;
            Vector3 newPos = pos + projectV + newN;
            transform.position = newPos;
            transform.rotation *= q;
        }
    }

    摄像机

    Clear Flags(清除标志):摄像机剔除标志选择
    ----Skybox(天空盒):增加显卡渲染负担,2D游戏看不到天空的可以选择 Solid Color纯色
    ----Solid Color(纯色):
    ----Depth only(只深度):
    ----Don't Clear(不清除):会留下残影,此很少用
    BackGround:背景色(当选为Solid Color的时候,背景颜色是可选的)
    Culling Mask(剔除遮罩):通过层级来筛选这个Camera要渲染的游戏物体
    1、给Plane和Sphere添加层级
    2、辅摄像机添加Depth only,Depth改为1,比主摄像机Depth0要大
    3、主摄像机剔除小球,辅摄像机只保留小球

    Projection:决定了此Camera的投影方式
    ----Perspective(透视投影,近大远小):发散形视角
    --------Field of View(视野角度大小):可以做运动相机的鱼眼镜头
    ----Orthographic(正交投影,没有近大远小):非发散形视角,以矩形平行出去,2D游戏,暗黑2
    --------Size(视口大小):调整正交投影下视口大小的,通过分辨率运算得出
    1方块=1米=100像素
    Size = 屏幕分辨率 / 100(unity默认一个方格的像素) / 2(屏幕高度的一半)
    正好可以把背景投射完整
    Clipping Planes(剔除裁剪平面):调整摄像机的近裁面和远裁面,只有在近裁面和远裁面之间的游戏物体,才会被渲染显示
    ----Near:近裁面(最小值0.01)
    ----Far:远裁面
    Viewpoint Rect(视口矩形框):调整摄像机渲染的游戏画面在整个游戏屏幕中的比例尺寸,以屏幕左下角为基准点
    作用:分屏游戏,小地图(耗费性能,用UI等比例投放)
    ----X、Y:游戏画面相对于屏幕左下角的位置
    ----W、H:游戏画面占屏幕的宽、高
    Depth(深度):摄像机深度越大,越后渲染,后渲染的会把先渲染的覆盖掉
    使用:
    1、渲染顺序
    2、CS枪支单独摄像机渲染,再叠加到人物的主摄像机
    渲染次序,先渲染场景(-1),后渲染枪支(0),空白部分用Clear Flags - Depth only渲染
    Rendering path(渲染路径):预设渲染路径、延时渲染路径,定点照明渲染路径
    Target Texture(目标贴图):摄像机渲染出来的画面可以投射到Game视图中,也可以投射到一张纹理贴图上
    作用:电脑、赛车游戏的后视镜
    Occlusion Culing():渲染范围剔除
    Allow HDR(高动态贴图):需要延时渲染路径
    Allow MSAA(抗锯齿):性能消耗大,不推荐使用,市面流行官方免费插件TSAA,需自行导入
    Allow Dynamic Reso:
    摄像机跟随功能
    Unity2017增加智能相机
     
    VS2015的ReSharper插件安装
    强大的智能提示

    补充内容-查找篇:

    标签
    GameObject.Find();
    GameObject.FindGameObjectsWithTag();//查找所有带标签的游戏物体
    GameObject.FindGameObjectWithTag();
    GameObject.CompareTag();
     
    层级
    前8个层级是Unity默认的,无法修改
    碰撞层级矩阵取消,可以取消敌人之间的碰撞

    更换天空球的材质

    赛车游戏
    车轮碰撞器

    第三人称视角:人

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    public class ThirdPersonalCameraControl : MonoBehaviour {
        public float moveSpeed = 5;
        public float rotateSpeed = 60;
        private float keyboard_h;
        private float keyboard_v;
        private Camera camera;
        // Use this for initialization
        void Start () {
            camera = Camera.main;
        }
           
           // Update is called once per frame
           void Update () {
            keyboard_h = Input.GetAxis("Horizontal");
            keyboard_v = Input.GetAxis("Vertical");
            PlayerMove();
        }
        void PlayerMove()
        {
            Vector3 cameraForward = Vector3.ProjectOnPlane(camera.transform.forward,Vector3.up).normalized;
            Vector3 cameraRight = Vector3.ProjectOnPlane(camera.transform.right, Vector3.up).normalized;
            transform.Translate(cameraForward * Time.deltaTime * moveSpeed * keyboard_v);
            transform.Translate(cameraRight * Time.deltaTime * moveSpeed * keyboard_h);
        }
    }
    第三人称视角:摄像机
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    public class ThirdCameraControl : MonoBehaviour {
        public Transform player;
        public float rotateSpeed = 60;
        private float mouse_h;
        private float mouse_v;
        private float mouseWheel;
        private Vector3 player2CameraVector;
        // Use this for initialization
        void Start () {
            player2CameraVector = transform.position - player.position;
        }
           
           // Update is called once per frame
           void Update () {
            mouse_h = Input.GetAxis("Mouse X") * rotateSpeed;
            mouse_v = -Input.GetAxis("Mouse Y") * rotateSpeed;
            mouseWheel = Input.GetAxis("Mouse ScrollWheel") * rotateSpeed;
            PlayeRotate();
            MouseScrollWheel();
           
        }
        void PlayeRotate()
        {
            //一个控制人物(左右转向,放人物身上)
            transform.Rotate(Vector3.up * Time.deltaTime * rotateSpeed * mouse_h);
            Vector3 eulurVector3 = new Vector3(mouse_v, mouse_h, 0);
            Quaternion targetQ = Quaternion.Euler(eulurVector3);
            Vector3 newVector3 = targetQ * player2CameraVector;
            transform.position = player.position + newVector3;
            transform.LookAt(player);
            //思考题:上下无法移动
        }
        void MouseScrollWheel()
        {
            player2CameraVector = player2CameraVector + player2CameraVector.normalized * mouseWheel;
            Vector3 eulurVector3 = new Vector3(mouse_v, mouse_h, 0);
            Quaternion targetQ = Quaternion.Euler(eulurVector3);
            Vector3 newVector3 = targetQ * player2CameraVector;
            transform.position = player.position + newVector3;
            transform.LookAt(player);
            //限制
        }
    }

    第一人称视角:人

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    public class FirstPersonalCameraControl : MonoBehaviour {
        public float moveSpeed = 5;
        public float rotateSpeed = 60;
        private float keyboard_h;
        private float keyboard_v;
        private float mouse_h;
        private float mouse_v;
        // Use this for initialization
        void Start () {
                  
           }
           
           // Update is called once per frame
           void Update () {
            keyboard_h = Input.GetAxis("Horizontal");
            keyboard_v = Input.GetAxis("Vertical");
            mouse_h = Input.GetAxis("Mouse X");
            mouse_v = Input.GetAxis("Mouse Y");
            PlayerMove();
            PlayeRotate();
        }
        void PlayerMove()
        {
            //写两个代码:一个控制人物(左右转向,放人物身上),一个控制摄像机(上下转向,放摄像机身上)
            transform.Translate(Vector3.forward * Time.deltaTime * moveSpeed * keyboard_v);
            transform.Translate(Vector3.right * Time.deltaTime * moveSpeed * keyboard_h);
        }
        void PlayeRotate()
        {
            //一个控制人物(左右转向,放人物身上)
            transform.Rotate(Vector3.up * Time.deltaTime * rotateSpeed * mouse_h);
        }
    }

    第一人称视角:摄像机

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    public class FirstCameraControl : MonoBehaviour {
        //上下转动(180)要比左右转动(360)角度小
        public float rotateSpeed = 60;
        private float mouse_v;
        // Use this for initialization
        void Start () {
                  
           }
           
           // Update is called once per frame
           void Update () {
            mouse_v = Input.GetAxis("Mouse Y");
            PlayeRotate();
        }
        void PlayeRotate()
        {
            //一个控制摄像机(上下转动,放摄像机身上)
            transform.Rotate(Vector3.right * Time.deltaTime * rotateSpeed * -mouse_v);
            //限制摄像机上下转动幅度
        }
    }

    汽车

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    public class CarMove : MonoBehaviour {
        public float moveSpeed = 5;
        public float rotateSpeed = 30;
        private float keyboard_h;
        private float keyboard_v;
        // Use this for initialization
        void Start()
        {
        }
        // Update is called once per frame
        void Update()
        {
            keyboard_h = Input.GetAxis("Horizontal");
            keyboard_v = Input.GetAxis("Vertical");
            transform.Translate(Vector3.forward * Time.deltaTime * moveSpeed * keyboard_v);
            transform.Rotate(Vector3.up * Time.deltaTime * rotateSpeed * keyboard_h);
        }
    }
    摄像机
    SmoothDamp,平滑阻尼,从固定的时间内到达某个位置,可用于摄像机跟随
    velocity是Vector3类的结构体,不能直接对外传值,只能用ref传引用的地址,如果有多个物体伴随移动,可以用velocity的速度去控制
    ref velocity,返回平滑阻尼的当前帧的速度(在Vector3各方向上的速度)
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    public class CarCameraController : MonoBehaviour {
        public Transform car;
        public Transform lookTrans;
        public float followTime = 0.5f;
        private Vector3 currentVelocity;
        // Use this for initialization
        void Start()
        {
        }
        // Update is called once per frame
        void Update()
        {
            transform.position = Vector3.SmoothDamp(transform.position, car.position, ref currentVelocity, followTime);
            Vector3 dir = lookTrans.position - transform.position;
            Quaternion targetQuat = Quaternion.LookRotation(dir);
            transform.rotation = Quaternion.Slerp(transform.rotation, targetQuat, 0.1f);
        }
    }

    对象池

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    public class PlayerControl : MonoBehaviour {
        public float moveSpeed = 1;
        Transform firePos;
        private void Awake()
        {
            firePos = transform.Find("firePos");
        }
           void Update () {
            Vector3 moveDir = new Vector3(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"), 0);
            transform.Translate(moveDir * Time.deltaTime * moveSpeed);
            if(Input.GetKeyDown(KeyCode.Space))
            {
                // 通过实例化创建子弹   替换成对象池管理
                //Instantiate(bulletPrefab, firePos.position, Quaternion.identity);
                PoolManager.Instance.Spawn(firePos.position, Quaternion.identity);//从对象池中取出游戏物体,要记得给对象赋于位置和方向
            }
             
                  
           }
    }
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    public class BossControl : MonoBehaviour {
        public int hp = 1000;
           void Start () {
                  
           }
           
           void Update () {
                  
           }
        private void OnTriggerEnter(Collider other)
        {
            if(other.gameObject.tag == "Bullet")
            {
                hp -= 10;
                // 子弹销毁        替换成对象池管理
                //Destroy(other.gameObject);
                PoolManager.Instance.Push(other.gameObject);
                if(hp <= 0)
                {
                    Destroy(this.gameObject);
                }
            }
        }
    }
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    public class PoolManager : MonoBehaviour
    {
        private static PoolManager instance = null;
        public static PoolManager Instance { get { return instance; } }
        public GameObject bulletPrefab;
        public List<GameObject> bulletPool = new List<GameObject>();
        // 列表来管理
        // 创建的时候 从列表中取一个出来 激活
        // 销毁的时候 把这个要销毁的游戏物体 失活, 放到列表中
        // 把游戏物体 激活、失活
        void Awake()
        {
            instance = this;
        }
        // 从对象池中取游戏物体
        public GameObject Spawn(Vector3 pos, Quaternion qua)
        {
            GameObject go;
            if (bulletPool.Count == 0)
            {
                go = Instantiate(bulletPrefab, pos, qua);
            }
            else
            {
                go = bulletPool[bulletPool.Count - 1];
                go.SetActive(true);
                bulletPool.RemoveAt(bulletPool.Count - 1);
                go.transform.position = pos;
                go.transform.rotation = qua;
               
            }
              //粒子特效的拖尾问题处理
            //ParticleSystem ps = go.GetComponent<ParticleSystem>();
            //if (ps) ps.Clear();
            //ParticleSystem[] pses = go.GetComponentsInChildren<ParticleSystem>();
            //foreach (var item in pses)
            //{
            //    item.Clear();
            //}
            TrailRenderer tr = go.GetComponent<TrailRenderer>();//TrailRenderer的拖尾问题处理
            tr.Clear();
            //ps.Play();
            //ps.Pause();
            return go;
        }
        // 把游戏物体放回对象池
        public void Push(GameObject go)
        {
            go.SetActive(false);
            bulletPool.Add(go);
        }
    }

    Invoke,延时调用函数

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    public class BulletMove : MonoBehaviour {
        public float moveSpeed = 10;
           void Start () {
            // 销毁     替换成对象池管理
            //Destroy(this.gameObject, 5f);
            Invoke("PushBack", 5f);  // 延迟调用
                  
           }
           
           void Update () {
            transform.Translate(Vector3.forward * Time.deltaTime * moveSpeed);
           }
        void PushBack()
        {
            PoolManager.Instance.Push(this.gameObject);
        }
    }
  • 相关阅读:
    网络流24题-运输问题
    ASP.NET API
    面向对象理解
    冒泡排序
    HTTP Header 缓存
    HTTP Header
    Flask学习笔记07之模板渲染
    Flask学习笔记06之@before_request请求之前执行
    Flask报错:AssertionError: View function mapping is overwriting an existing endpoint function: inner
    装饰器03之多个装饰器的执行顺序
  • 原文地址:https://www.cnblogs.com/vuciao/p/10362893.html
Copyright © 2011-2022 走看看