Unity移动与摄像机(第二次更新2023/12/13)

1.初学

        1.利用CharacterController实现简单移动
        2.利用四元数实现相机的太空移动

2.中学

3.大学


1.1利用CharacterController实现简单移动

        注意

                a.脚本自动添加CharacterController。如果给环境添加conllider可以实现碰撞效果。

                b.将player.cs作为某物体的组件。

player.cs直接复制版

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

public class SimpleMove : MonoBehaviour
{
    private CharacterController myCharacterController;
    private Transform mainCamera;
    private Vector3 cameraAngle = Vector3.zero;

    void Start()
    {
        //用代码添加CharacterController
        myCharacterController = transform.AddComponent<CharacterController>();
        //将主相机作为相机
        mainCamera = Camera.main.transform;
    }
    void Update()
    {
        //更新摄像机旋转角度
        cameraAngle.y += Input.GetAxis("Mouse X");
        cameraAngle.x -= Input.GetAxis("Mouse Y");
        mainCamera.eulerAngles = cameraAngle;

        //只将摄像机y轴参数传给物体
        transform.eulerAngles = new Vector3(0, cameraAngle.y, 0);

        //移动
        Vector3 motion = Vector3.zero;
        motion.x = Input.GetAxis("Horizontal") * Time.deltaTime * 5;
        motion.z = Input.GetAxis("Vertical") * Time.deltaTime * 5;
        myCharacterController.Move(transform.TransformDirection(motion));

        //摄像机跟随物体移动
        mainCamera.position = transform.position;
    }
}

1.2利用四元数实现相机的太空移动

        注意

                a.脚本实现完整功能需要主摄像机和目标物体(任意正方体,球体等都可以)。

                b.使用方法,先将脚本赋予任意物体。运行后自动进入自由移动模式,WASD移动,QE旋转。鼠标左键若击中某物体,将以该物体为中心进入行星模式。行星模式下,WASD旋转摄像机,F键退出行星模式。

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

public class SpaceSimpleMove : MonoBehaviour
{
    public float planetDistance = 1.0f;                                     //摄像机与星球之间的距离
    public float freeMove_CameraAngleMoveSpeed = 1.0f;                      //自由视角移动速度

    private Transform mainCamera;                                           //摄像机main
    private Vector2 cameraAngle = new Vector2(0, 0);                        //存储摄像机在行星模式下的状态
    private bool isSelection_Planet = false;                                //是否选择了行星
    private Transform selection_Planet = null;                              //当前选择的行星
    private bool freeMove = true;                                           //是否处于自由视角
    private Vector3 freeMove_CameraAngleChange = new Vector3(0, 0, 0);      //存放鼠标移动信息
    private Vector3 freeMove_CameraPositionChange = new Vector3(0, 0, 0);   //存放位置移动信息
    private bool camera_isInPlanet = false;                                 //相机是否处于行星模式

    void Start()
    {
        mainCamera = Camera.main.transform;
    }

    void Update()
    {
        //通过鼠标左键发射涉嫌以检测物体并以该物体为行星
        if (!isSelection_Planet && Input.GetMouseButtonDown(0))
        {
            //从摄像机发出射线的点
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
                isSelection_Planet = true;
                selection_Planet = hit.transform;
                freeMove = false;
                camera_isInPlanet = true;
            }
        }

        //自由移动模式
        if (freeMove)
        {
            freeMove_CameraAngleChange.x = -Input.GetAxis("Mouse Y");
            freeMove_CameraAngleChange.y = Input.GetAxis("Mouse X");
            //旋转
            if (Input.GetKey(KeyCode.Q))
            {
                freeMove_CameraAngleChange.z = 0.2f;
            }
            if (Input.GetKey(KeyCode.E))
            {
                freeMove_CameraAngleChange.z = -0.2f;
            }
            freeMove_CameraAngleChange *= freeMove_CameraAngleMoveSpeed;
            mainCamera.localRotation *= Quaternion.Euler(freeMove_CameraAngleChange);
            freeMove_CameraAngleChange = Vector3.zero;

            //移动
            if (Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0)
            {
                freeMove_CameraPositionChange.z += Input.GetAxis("Vertical");
                freeMove_CameraPositionChange.x += Input.GetAxis("Horizontal");
            }
            mainCamera.Translate(freeMove_CameraPositionChange * Time.deltaTime * 5);
            freeMove_CameraPositionChange = Vector3.zero;

        }

        //行星模式
        if (camera_isInPlanet)
        {
            cameraAngle.x += Input.GetAxis("Vertical");
            cameraAngle.y -= Input.GetAxis("Horizontal");
            planetDistance -= Input.GetAxis("Mouse ScrollWheel");

            //首先确定摄像机旋转
            Quaternion CameraAimAngle = mainCamera.rotation;
            CameraAimAngle *= Quaternion.Euler(cameraAngle.x, cameraAngle.y, 0);
            mainCamera.rotation = CameraAimAngle;
            //其次确定摄像机位置-通过摄像机角度反推摄像机位置
            mainCamera.position = selection_Planet.position - mainCamera.forward * planetDistance;

            cameraAngle = Vector2.zero;
        }

        //退出行星模式
        if (Input.GetKey(KeyCode.F))
        {
            isSelection_Planet = false;
            selection_Planet = null;
            freeMove = true;
            camera_isInPlanet = false;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

焦虑的狼堡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值