首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >unity3d 第三人称视角摄像机(线性锁视域)

unity3d 第三人称视角摄像机(线性锁视域)

原创
作者头像
用户5875740
修改2019-07-22 12:18:12
1.2K0
修改2019-07-22 12:18:12
举报

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.UI;

namespace ActorManage

{

public class Actor : MonoBehaviou

{

private const float radian = Mathf.PI / 180.0f; //1弧度的浮点数

private const float camBackLenth = 10.0f; //摄像机离角色多远

private const float speed = 3.0f; //角色行走速度

private float deltaTime = 0.0f; //这个变量是为了在以后可能要求时时更新,把罗技放到updata中,现在是固定帧更新

private Camera cam;

private bool isMove; //走路的开关正在走路时候是true 不准走就是false

private Vector3 RayAndTerrainPoint; //鼠标射线射中地形表面的

public Vector3 dis; //往哪边走

private Ray ray; //走路是用射线获取地表面高度

private RaycastHit[] hitInfo; //走路射线返回

private bool TouchDown;

private bool MoveDown;

//cam

private Vector3 camRotationX; //绕x轴选装的向量(旋转这个向量经过运算设置到摄像机上)

private Vector3 camRotationY; //绕y轴选装的向量(旋转这个向量经过运算设置到摄像机上)

private Matrix4x4 rotXMat; //绕x轴旋转矩阵

private Matrix4x4 rotYMat; //绕y轴旋转矩阵

private float m_xRot; //记录摄像机绕x轴旋转的角度(射线机被锁定在 0-90了初始化设置45度 )

private bool m_MouseDown; //记录鼠标是否按下

private float m_LastMousePosX; //上一个更新帧鼠标坐标x

private float m_LastMousePosY;

private float m_MouseRotSpeedX = 0.2f; //分别设置两个摄像机旋转的速度(一样的速度体验效果很差)

private float m_MouseRotSpeedY = 0.1f;

void Aweke()

{

#if UNITY_ANDROID

Debug.Log("这里是安卓设备^_^");

#endif

#if UNITY_IPHONE

Debug.Log("这里是苹果设备>_<");

#endif

#if UNITY_STANDALONE_WIN

Debug.Log("我是从Windows的电脑上运行的T_T");

#endif

}

// Use this for initialization

void Start()

{

rig = transform.FindChild("Capsule").gameObject.GetComponent<Rigidbody>();

deltaTime = Time.fixedDeltaTime;

isMove = false;

RayAndTerrainPoint = Vector3.zero;

dis = Vector3.zero;

cam = GameObject.Find("Camera").GetComponent<Camera>();

Camera.SetupCurrent(cam);

GameObject.Find("DebugText");

ray = new Ray(Vector3.zero, Vector3.zero);

TouchDown = false;

MoveDown = false;

//SetPosition(gameObject.transform.position);

camRotationX.x = 0.0f;

camRotationX.y = 0.0f;

camRotationX.z = -1.0f;

camRotationY.x = 0.0f;

camRotationY.y = 0.0f;

camRotationY.z = -1.0f;

cam.transform.forward = gameObject.transform.forward;

CameraInit(45.0f);

Vector3 v0;

v0.x = 33.0f;

v0.y = 50.0f;

v0.z = 23.0f;

SetActorPostion(v0);

}

// Update is called once per frame

//时时更新

void Updata()

{

}

//固定帧跟新

void FixedUpdate()

{

InputUpdata();

MoveUpdata();

CameraUpdata();

}

void InputUpdata()

{

#if UNITY_STANDALONE_WIN

if (Input.GetMouseButtonDown(1))

{

m_MouseDown = true;

m_LastMousePosX = Input.mousePosition.x;

m_LastMousePosY = Input.mousePosition.y;

}

else if (Input.GetMouseButtonUp(1))

{

m_MouseDown = false;

}

if (m_MouseDown == true)

{

CameraRotY((Input.mousePosition.x - m_LastMousePosX) * m_MouseRotSpeedX);

CameraRotX((Input.mousePosition.y - m_LastMousePosY) * m_MouseRotSpeedY);

m_LastMousePosX = Input.mousePosition.x;

m_LastMousePosY = Input.mousePosition.y;

return;

}

if (Input.GetMouseButtonUp(0))

{

GoToPostion(Input.mousePosition);

//Debug.Log(Input.mousePosition.ToString());

}

#endif

#if UNITY_ANDROID

if (Input.touchCount > 0)

{

Touch tc = Input.GetTouch(0);

TouchPhase tp = tc.phase;

// text.text = tp.ToString();

if (tc.phase == TouchPhase.Moved)

{

Vector2 dataPos = tc.deltaPosition;

//text1.text ="X: " + dataPos.x.ToString();

CameraRotY(dataPos.x);

CameraRotX(dataPos.y);

MoveDown = true;

}

else if (tp == TouchPhase.Stationary)

{

TouchDown = true;

}

else if (tp == TouchPhase.Ended)//弹起

{

if (TouchDown == true && MoveDown == false)

{

GoToPostion();

}

TouchDown = false;

MoveDown = false;

}

}

#endif

}

#if UNITY_ANDROID

void GoToPostion()

{

Ray ray = cam.ScreenPointToRay(Input.GetTouch(0).position);

hitInfo = Physics.RaycastAll(ray);

foreach (RaycastHit hit in hitInfo)

{

if (hit.transform.gameObject.name == "terrain" || hit.transform.gameObject.name == "road")

{

RayAndTerrainPoint = hit.point;

dis = RayAndTerrainPoint - gameObject.transform.position;

dis.Normalize();

//Debug.Log(RayAndTerrainPoint.ToString());

isMove = true;

break;

}

}

}

#endif

void GoToPostion(Vector2 pos)

{

Ray ray = cam.ScreenPointToRay(pos);

hitInfo = Physics.RaycastAll(ray);

foreach (RaycastHit hit in hitInfo)

{

if (hit.transform.gameObject.name == "terrain" || hit.transform.gameObject.name == "road")

{

RayAndTerrainPoint = hit.point;

GameObject obj = GameObject.Find("TestObj");

obj.transform.position = RayAndTerrainPoint;

dis = RayAndTerrainPoint - gameObject.transform.position;

dis.Normalize();

//Debug.Log(RayAndTerrainPoint.ToString());

isMove = true;

break;

}

}

}

public void OffMove()

{

isMove = false;

}

void MoveUpdata()

{

if (isMove == true)

{

if (SweepTest())

{

//Debug.Log(dis.ToString() + "test");

isMove = false;

}

else

{

SetPosition();

}

}

}

bool isSweep;

Rigidbody rig;

bool SweepTest()

{

RaycastHit[] rh;

rh = rig.SweepTestAll(dis, 0.3f);

foreach (RaycastHit r in rh)

{

//

if (r.transform == null || r.transform.parent == null)

{

continue;

}

if (r.transform.parent.name == "qiangti")

{

//Debug.Log(r.transform.gameObject.name);

isSweep = true;

return isSweep;

}

}

isSweep = false;

return isSweep;

}

//慢慢走到目标点

void SetPosition()

{

// Debug.Log("SetPosition");

Vector3 v1, v2;

v1 = gameObject.transform.position + (dis * (speed * deltaTime));

v1.y = v1.y + 2.0f;

v2.x = 0.0f;

v2.y = -1.0f;

v2.z = 0.0f;

ray.origin = v1;

ray.direction = v2;

hitInfo = Physics.RaycastAll(ray);

float height = 0.0f;

foreach (RaycastHit hit in hitInfo)

{

if (hit.transform.gameObject.name == "terrain" || hit.transform.gameObject.name == "road")

{

if (height < hit.point.y)

{

height = hit.point.y;

}

}

}

Vector3 v3;

v3.x = v1.x;

v3.z = v1.z;

v3.y = height;

gameObject.transform.position = v3;

Vector3 v4, v5;

v4.x = RayAndTerrainPoint.x;

v4.y = 0.0f;

v4.z = RayAndTerrainPoint.z;

v5.x = gameObject.transform.position.x;

v5.y = 0.0f;

v5.z = gameObject.transform.position.z;

float lenth = (v4 - v5).magnitude;

//Debug.Log(lenth.ToString());

if (lenth < speed * deltaTime *3.0f)

{

isMove = false;

}

}

//直接把主角放到地图指定地点

void SetActorPostion(Vector3 vPos)

{

Vector3 v1, v2;

v1 = vPos;

v1.y = v1.y + 2.0f;

v2.x = 0.0f;

v2.y = -1.0f;

v2.z = 0.0f;

ray.origin = v1;

ray.direction = v2;

hitInfo = Physics.RaycastAll(ray);

float height = 0.0f;

foreach (RaycastHit hit in hitInfo)

{

if (hit.transform.gameObject.name == "terrain" || hit.transform.gameObject.name == "road")

{

if (height < hit.point.y)

{

height = hit.point.y;

}

}

}

v1.y = height;

gameObject.transform.position = v1;

}

void CameraUpdata()

{

Vector3 v1;

float x, z;

float k = 1.0f - (m_xRot / 90.0f);

x = (camRotationY * camBackLenth).x * k;

z = (camRotationY * camBackLenth).z * k;

v1.x = x + gameObject.transform.position.x;

v1.z = z + gameObject.transform.position.z;

v1.y = (camRotationX * camBackLenth).y + gameObject.transform.position.y;

if (v1 == null)

{

Debug.Log("v1");

}

if (cam == null)

{

Debug.Log("cam");

}

cam.transform.position = v1;

cam.transform.LookAt(gameObject.transform.position);

}

void RotXMat(float x, ref Matrix4x4 retMat)

{

Matrix4x4 m1;

float xCos, xSin;

m1 = Matrix4x4.identity;

xCos = Mathf.Cos(x * radian);

xSin = Mathf.Sin(x * radian);

m1.m11 = xCos;

m1.m22 = xCos;

m1.m12 = -xSin;

m1.m21 = xSin;

retMat = m1;

}

void RotYMat(float y, ref Matrix4x4 retMat)

{

Matrix4x4 m2;

float yCos, ySin;

m2 = Matrix4x4.identity;

yCos = Mathf.Cos(y * radian);

ySin = Mathf.Sin(y * radian);

m2.m00 = yCos;

m2.m22 = yCos;

m2.m20 = -ySin;

m2.m02 = ySin;

retMat = m2;

}

void CameraRotX(float k)

{

if (k < 0.0f && m_xRot - k >= 90.0f)

{

return;

}

if (k > 0.0f && m_xRot - k <= 0.0f)

{

return;

}

m_xRot -= k;

Matrix4x4 matRotX = Matrix4x4.identity;

RotXMat(-k, ref matRotX);

camRotationX = matRotX.MultiplyPoint(camRotationX);

camRotationX.Normalize();

}

void CameraRotY(float k)

{

if (Mathf.Abs(k) < 1)

{

return;

}

Matrix4x4 matRotY = Matrix4x4.identity;

RotYMat(k, ref matRotY);

camRotationY = matRotY.MultiplyVector(camRotationY);

}

void CameraInit(float k)

{

m_xRot = k;

Matrix4x4 matRotX = Matrix4x4.identity;

RotXMat(k, ref matRotX);

camRotationX = matRotX.MultiplyPoint(camRotationX);

camRotationX.Normalize();

CameraUpdata();

}

//类内

}

}

https://share.weiyun.com/5qqvp6C

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
访问管理
访问管理(Cloud Access Management,CAM)可以帮助您安全、便捷地管理对腾讯云服务和资源的访问。您可以使用CAM创建子用户、用户组和角色,并通过策略控制其访问范围。CAM支持用户和角色SSO能力,您可以根据具体管理场景针对性设置企业内用户和腾讯云的互通能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档