前言
素材来自unity官方教程。
- 实现人物移动,相机跟随,但有一定的后滞效果
- 类似小小梦魇的视角旋转:小小梦魇相机可以左右旋转,但非常有限。并且玩家如果放开控制键,视角自动回到原处。
不使用插件,简单实现。
效果如下:
JohnHaunt
代码实现
using UnityEngine;
public class CameraCTRL : MonoBehaviour
{
// get the character transform
private Transform character;
private PlayerControl player;
// get offset from camera to character
private Vector3 offset;
[Range(1f,2f)]
public float camSpeed = 1.5f;
public float maxCameraRotX= 5f;
public float minCameraRotX = -5f;
// check whether mouse is always held
private bool isMouse = false;
//
private float pre_rotx = 0f;
private Vector3 cam_rot_ori;
// check mouse
private float cur_mouse_Y = 0f;
private float pre_mouse_Y = 0f;
private float delta_mouse_Y = 0f;
void Start()
{
character = GameObject.Find("JohnLemon").transform;
player = GameObject.Find("JohnLemon").GetComponent<PlayerControl>();
offset = this.transform.position - character.position;
if (minCameraRotX >= maxCameraRotX)
{
minCameraRotX = maxCameraRotX - 5f;
}
cam_rot_ori = transform.eulerAngles;
pre_rotx = transform.eulerAngles.x;
camPosInitial();
}
// Update is called once per frame
void Update()
{
//移动
this.transform.position = Vector3.Lerp(this.transform.position, character.position + offset, Time.deltaTime*camSpeed);
Vector3 moveDirection =player.moveDirection;
//俯仰
if (Input.GetMouseButton(0))
{
isMouse = true;
cur_mouse_Y = Input.mousePosition.y;
if (pre_mouse_Y != 0f)
{
delta_mouse_Y = cur_mouse_Y - pre_mouse_Y;
Vector3 rot = Vector3.zero;
if (delta_mouse_Y < 0f)
{
rot.x = pre_rotx-minCameraRotX;
rot.y = transform.eulerAngles.y;
transform.eulerAngles = Vector3.Lerp(transform.eulerAngles, rot,Time.deltaTime*camSpeed);
}
else if (delta_mouse_Y > 0f)
{
rot.x = pre_rotx-maxCameraRotX;
rot.y = transform.eulerAngles.y;
transform.eulerAngles = Vector3.Lerp(transform.eulerAngles, rot,Time.deltaTime*camSpeed);
}
}
pre_mouse_Y = cur_mouse_Y;
}
if (Input.GetMouseButtonUp(0))
{
pre_mouse_Y = 0f;
isMouse = false;
}
if (!isMouse)
{
cam_rot_ori.y = transform.eulerAngles.y;//y is free;
transform.eulerAngles = Vector3.Lerp(transform.eulerAngles, cam_rot_ori, Time.deltaTime * camSpeed);
}
}
void camPosInitial()
{
// fix camera
Vector3 look_dir = character.position - transform.position ;
look_dir.y = 0f;
look_dir.Normalize();
Vector3 player_dir = character.forward;
player_dir.y = 0;
player_dir.Normalize();
float angle = Mathf.Acos(look_dir.x*player_dir.x+look_dir.z*player_dir.z)*180/Mathf.PI;
transform.RotateAround(character.position,character.up,-angle);
}
}