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);
    }
}

 

posted @ 2019-02-11 19:09  vuciao  阅读(1928)  评论(0编辑  收藏  举报