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