Unity中简单实现移动端第三人称视角

1.场景搭建

主要包含相机、地形、代表玩家的方块,相机需要跟随该方块。

 由于需要接收触屏事件,因此需要设置模拟器

将代表玩家的方块的Tag设置为Player,用于之后相机碰撞检测过滤。

2.编写脚本

新建脚本,命名为TPSCamera

首先编写常用的属性, 将其挂载到Main Camera上。

将Cube绑定到followTarget上,Main Camera绑定到controlCamera上

public class TPSCamera : MonoBehaviour
{
    public Transform followTarget = null; // 相机拍摄的物体

    public Vector2 rotate; // 相机的转动角度(绕着x轴和y轴)

    public float rotateSpeed = 0.6f; // 相机的转向速度

    public float moveSpeed = 10; // 相机的移动速度

    public float maxY = 80; // 相机向下移动的最大角度

    public float minY = -80; // 相机向下移动的最小角度

    public float viewSize = 60; // 相机的视野

    public float defaultAngle = -135; // 默认角度

    public float radius = 5; // 相机与目标物体的距离

    public float height = 0.8f; // 焦点与目标物体的高度差

    private Camera controlCamara; // 目标相机

    void Start()
    {
        controlCamara = this.GetComponent<Camera>();
        Input.multiTouchEnabled = true;
    }
}

 实现触屏移动视角的代码,这里我们找到接触到右半边屏幕的手指,并记录它的位置。

    private int lastfingerId = -1;
    void FixedUpdate()
    {
        for (int i = 0; i < Input.touchCount; i++)
        {
            Touch touch = Input.GetTouch(i);
            // 找到接触到右半边的手指
            if (touch.position.x < UnityEngine.Screen.width / 2)
                continue;
            if (lastfingerId != touch.fingerId && lastfingerId != -1)
                continue;
            switch (touch.phase)
            {
                case TouchPhase.Began:
                    lastfingerId = touch.fingerId;
                    break;
                case TouchPhase.Moved:
                    rotate.x += touch.deltaPosition.x * rotateSpeed;
                    rotate.y += touch.deltaPosition.y * rotateSpeed;
                    if (rotate.y < -60)
                    {
                        rotate.y = -60;
                    }
                    else if (rotate.y > 45)
                    {
                        rotate.y = 45;
                    }
                    break;
                case TouchPhase.Ended:
                    lastfingerId = -1;
                    break;
            }
            break;
        }
    }

同步相机位置并实现相机的碰撞检测


    void LateUpdate()
    {
        if (followTarget == null) return;
        Transform self = controlCamera.transform;
        Vector3 startPosition = self.position;
        Vector3 endPosition;

        Vector3 targetPos = followTarget.position;
        targetPos.y += height;

        Vector2 v1 = CalcAbsolutePoint(rotate.x, radius);
        endPosition = targetPos + new Vector3(v1.x, 0, v1.y);

        Vector2 v2 = CalcAbsolutePoint(rotate.x + defaultAngle, 1);
        Vector3 viewPoint = new Vector3(v2.x, 0, v2.y) + targetPos;

        float dist = Vector3.Distance(endPosition, viewPoint);
        Vector2 v3 = CalcAbsolutePoint(rotate.y, dist);
        endPosition += new Vector3(0, v3.y, 0);

        RaycastHit hit;
        if (Physics.Linecast(targetPos, endPosition, out hit))
        {
            string name = hit.collider.gameObject.tag;
            // 将玩家的Tag设置为Player
            if (!(name == "MainCamera" || name.StartsWith("Player")))
            {
                endPosition = hit.point - (endPosition - hit.point).normalized * 0.2f;
            }
        }
        self.position = Vector3.Lerp(startPosition, endPosition, Time.deltaTime * moveSpeed);

        Quaternion rotateQ = Quaternion.LookRotation(viewPoint - endPosition);
        self.rotation = Quaternion.Slerp(transform.rotation, rotateQ, Time.deltaTime * moveSpeed);
    }

    public static Vector2 CalcAbsolutePoint(float angle, float dist)
    {
        float radian = -angle * (Mathf.PI / 180);
        float x = dist * Mathf.Cos(radian);
        float y = dist * Mathf.Sin(radian);
        return new Vector2(x, y);
    }

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值