RPG游戏人物视角控制,相机跟随


   因为被人物视角控制困扰了好久,终于搞明白了,所以想记下来再梳理一遍,也希望大神看到能给我这个新人一些建议。

首先列出我参考了的博客:

游戏之角色移动和相机跟随

雨松大神解读的官方相机跟随脚本(我只看了里面的相机跟随,太懒,哈哈哈哈安静

我的这个视角控制是相机跟随主角移动,旋转,滑动滚轮对视角进行放大缩小。要实现的功能如下(模仿剑三的人物控制,然而和它大的相比差太多了,跪求大神指点大哭):

1.在键盘上,按W,S朝前/后移动,A,D朝左右旋转人物角色(相机跟随旋转或移动)

2.在鼠标上,按右键对人物进行旋转(相机跟随旋转),按左键旋转人物(相机不跟随旋转),滚轮对视角进行缩放。


一.知识储备(关于旋转的所有知识点)

1. Input.GetAxis()  :该方法用于在Unity3D中根据坐标轴名称返回虚拟坐标系中的值,通常情况下,使用控制器和键盘输入时此值范围在-1到1之间。

2.欧拉角eulerAngles: 这是一个Vector3类型的值,我看官方的解释是在z,y,x旋转多少度,然而用的时候,比如下面的代码,就是将transform的rotation设置为了(0,10,0);

transform.eulerAngle=new vecror3(0,10,0)

              这个方法的好处是能将Quaternion 四元数转化为直观的vector3,想transform.eulerAngles和Quaternion.eulerAngles都是这个意思

下面的代码是欧拉角在旋转的应用场景,物体会绕Y轴进行旋转,但是,注意他的旋转坐标先变成(0,5,0)然后再开始旋转,在做的时候终于搞明白了这个

float mY = 5.0;  
  
void Update ()   
{  
    mY += Input.GetAxis("Horizontal");  
    transform.eulerAngles =new Vector3(0,mY, 0);  
}  
3.插值(lerp) 

currentHeight = Mathf.Lerp(currentHeight,wantedHeight,heightDamping*Time.deltaTime)

由当前高度到达想要的高度,在heightDamping*Time.deltaTime的时间内完成

这个主要是让旋转或者移动变得平滑,不会很僵硬。

4.

Quaternion乘法重载(两种形式,这里用到第二种):

static operator*(lhs:Quaternion, rhs:Quaternion):Quaternion
static operator*(rotation:Quaternion, point:Vector3):Vector3
这两个重载是有很大区别的,第一个是计算对一个物体旋转lhs以后再旋转rhs,这整个结果实际上相当于旋转了多少,参数和返回值都是 Quaternion,也就是旋转角度;而第二个是计算笛卡尔坐标系下某一个点,在经过rotation的旋转之后,会出现在那个位置,返回值是 Vector3.(
通俗的讲Quaternion * Vector3就是Vector3进行一次Quaternion 旋转




好了,大概的就是这样子,现在就是我的代码了

1.挂在相机上的

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class cameraController : MonoBehaviour {
      private moveController mc;      //获取人物控制组件
      Transform target;         //相机跟随的目标位置
     
      public float rotationDamping = 6;         //相机跟随人物的旋转速度
      public  float zoomSpeed=4;                //鼠标滚轮滑动速度
 
      private float h1;                      //点击鼠标右键,存储鼠标Y方向位移
      private float distance = 0;     //相机和目标的距离
    //private float height = 1f;       //相机和目标的高度
    //private float heightDamping = 1;
    // Vector3 offsetPosition;

    // Use this for initialization
    void Start () {
       
          target = GameObject.FindGameObjectWithTag(Tag.player).transform;
          mc = target.gameObject.GetComponent<moveController>();
          distance = Vector3.Distance(new Vector3(0, 0, target.position.z), new Vector3(0, 0, transform.position.z));
         
        //offsetPosition = target.position - transform.position;
    }

    // Update is called once per frame
    void Update () {
        //transform.position = target.position - offsetPosition;

        flowTarget();
        zoomView();
        UpAndDownView();
        
       }
  
     /// <summary>
     /// 相机跟随人物移动旋转
     /// </summary>
    void flowTarget()
    {

        float wantedRotationAngle = target.eulerAngles.y;    //要达到的旋转角度
        //float wantedHeight = target.position.y + height;     //要达到的高度
        float currentRotationAngle = transform.eulerAngles.y; //当前的旋转角度
        float currentHeight = transform.position.y;           //当前的高度
        if (mc.cameraIsRotate)
        {
            currentRotationAngle = Mathf.LerpAngle(currentRotationAngle, wantedRotationAngle, rotationDamping * Time.deltaTime);
        }
       // currentHeight = Mathf.Lerp(currentHeight, wantedHeight, heightDamping * Time.deltaTime);    //由当前高度达到要达到的高度
        Quaternion currentRotation = Quaternion.Euler(transform.eulerAngles.x, currentRotationAngle, 0);
        // float currentRotation=1;   //防止主角回头摄像机发生旋转,  这里不用
     
        Vector3 ca = target.position - currentRotation * Vector3.forward * distance;     //tt是相机的位置      
        // transform.position = target.position-currentRotation * Vector3.forward * distance;

        transform.position = new Vector3(ca.x, transform.position.y,ca.z);      //最后得到的相机位置
        transform.rotation = currentRotation;                                   //最后得到相机的旋转角度
        // transform.LookAt(target.position);

    }

    /// <summary>
    /// 滚轮控制缩放
    /// </summary>
    void zoomView()
    {
        float scrollWheel = Input.GetAxis("Mouse ScrollWheel") * zoomSpeed;
        distance -= scrollWheel;
        if (distance>5.6f)
        {
            distance = 5.6f;
        }
        if (distance<0.9f)
        {
            distance = 0.9f;
        }
    }
    /// <summary>
    /// 摄像头上下视角
    /// </summary>
    void UpAndDownView()
    {

 
        if (Input.GetMouseButton(1))
        {
            h1= Input.GetAxis("Mouse Y") * rotationDamping;
            Vector3 originalPosition = transform.position;
            Quaternion originalRotation = transform.rotation;
            transform.RotateAround(target.position, -target.right, h1);     //决定因素position和rotation
            float x = transform.eulerAngles.x;
           if (x<-10||x>80)
            {
                transform.position = originalPosition;
                transform.rotation = originalRotation;
            }
         
        }
    }
}



2.挂在人物上的

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class moveController : MonoBehaviour {
    public float speed = 3;              //人物移动速度
    public float rotatinDamping =4;    //人物旋转的速度
    public float mouse1RotateDamping = 4;
  
    public bool cameraIsRotate=true;      //判断相机是否跟随人物旋转(点击鼠标左键可观看角色)

    
    private float h1;                //点击鼠标右键,存储鼠标X方向位移
    private float h2;                //点击鼠标左键,存储鼠标X方向位移

    float currentOnClickMouse1AngleY = 0;     //鼠标右击时人物当前的Y轴度数
    float currentCameraAngleY = 0;           //鼠标左击时相机当前的Y轴度数


    public GameObject cam;                  //人物后面的相机
    private CharacterController characterContro;   //角色控制器组件
    // Use this for initialization
    void Start () {
        characterContro = this.GetComponent<CharacterController>();
        cam = GameObject.FindGameObjectWithTag(Tag.MainCamera);
       
    }
	
	// Update is called once per frame
	void Update () {
        forwardOrBack();
        rotate();
        mouseControllerRotation();

    }
    /// <summary>
    /// 向前向后移动
    /// </summary>
    void forwardOrBack()
    {
        if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
        {
            characterContro.Move(transform.forward * speed * Time.deltaTime);
        }
        else
            if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
        {
            characterContro.Move(-transform.forward * speed * Time.deltaTime);
        }
    }
    /// <summary>
    /// 按左右旋转
    /// </summary>
    void rotate()
    {
        if (Input.GetKey(KeyCode.D))
        {
            transform.Rotate(Vector3.up*rotatinDamping);
        }
        if (Input.GetKey(KeyCode.A))
        {
            transform.Rotate(-Vector3.up * rotatinDamping);
        }
    }
    /// <summary>
    /// 鼠标控制旋转
    /// </summary>
    void mouseControllerRotation()
    {
       if (Input.GetMouseButtonDown(1))
         {
            currentOnClickMouse1AngleY = transform.eulerAngles.y;
            h1 = 0;
         }
      if (Input.GetMouseButton(1))
        {
          
             h1+= Input.GetAxis("Mouse X")*mouse1RotateDamping;
             transform.eulerAngles = new Vector3(transform.eulerAngles.x, h1+currentOnClickMouse1AngleY, transform.eulerAngles.z) ;

        }

        if (Input.GetMouseButtonDown(0))
        {
           currentCameraAngleY =cam.transform.eulerAngles.y;
            h2 = 0;
        }
        if (Input.GetMouseButton(0))
        {
           // float currentOnClickMouse1Angle = transform.eulerAngles.y;
            cameraIsRotate = false;
            h2 += Input.GetAxis("Mouse X") * mouse1RotateDamping;
            cam.transform.eulerAngles = new Vector3(cam.transform.eulerAngles.x, h2+currentCameraAngleY, cam.transform.eulerAngles.z);
           
        }
        else
        {
            cameraIsRotate = true;
        }
    }
}

不会上传动态图,所以不好意思没有效果图啦~。

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值