Unity3d 摄像机跟随 右键旋转

调用 

摄像机开始跟随角色
CameraMMO.CameraFollow(gameObject, GameObject.FindGameObjectWithTag("Player").transform, Camera.main.transform).enabled = true;
//不跟随则相反
CameraMMO.CameraFollow(gameObject, GameObject.FindGameObjectWithTag("Player").transform, Camera.main.transform).enabled = false;

CameraMMO.cs



// We developed a simple but useful MMORPG style camera. The player can zoom in
// and out with the mouse wheel and rotate the camera around the hero by holding
// down the right mouse button.
//
// Note: we turned off the linecast obstacle detection because it would require
// colliders on all environment models, which means additional physics
// complexity (which is not needed due to navmesh movement) and additional
// components on many gameobjects. Even if performance is not a problem, there
// is still the weird case where if a tent would have a collider, the inside
// would still be part of the navmesh, but it's not clickable because of the
// collider. Clicking on top of that collider would move the agent into the tent
// though, which is not very good. Not worrying about all those things and
// having a fast server is a better tradeoff.
using UnityEngine;

/// <summary>
/// 一款简单但实用的MMORPG风格相机。
/// 1.跟随玩家
/// 2.缩小拉镜与玩家的距离
/// 3.按下鼠标右键 摄像机绕角色旋转
/// </summary>
public class CameraMMO : MonoBehaviour
{
     Transform targetT;
     Transform cameraT;


    public int mouseButton = 1; // right button by default

    public float distance = 20;
    public float minDistance = 3;
    public float maxDistance = 25;

    public float zoomSpeedMouse = 1;
    public float zoomSpeedTouch = 0.2f;
    public float rotationSpeed = 2;

    public float xMinAngle = -40;
    public float xMaxAngle = 80;

    float rightDownDuration = 0.75f;
    private float timer = 0f;
    bool startRotate = false;

    // the target position can be adjusted by an offset in order to foucs on a
    // target's head for example
    public Vector3 offset = Vector3.zero;

    // the layer mask to use when trying to detect view blocking
    // (this way we dont zoom in all the way when standing in another entity)
    // (-> create a entity layer for them if needed)
    //public LayerMask layerMask;

    // store rotation so that unity never modifies it, otherwise unity will put
    // it back to 360 as soon as it's <0, which makes a negative min angle
    // impossible
    Vector3 rot;

    /// <summary>
    /// 跟随角色
    /// </summary>
    /// <param name="go">CameraMMOcs挂在哪个物体上执行</param>
    /// <param name="targetT">角色</param>
    /// <param name="cameraT">摄像机</param>
    /// <returns></returns>
    public static CameraMMO CameraFollow(GameObject go,Transform targetT, Transform cameraT)
    {
        CameraMMO _cameraMMO = go.GetComponent<CameraMMO>();
        if (_cameraMMO == null)
        {
            _cameraMMO = go.AddComponent<CameraMMO>();
            _cameraMMO.Init(targetT, cameraT);
        }
        return _cameraMMO;
    }
 

    #region Init() 初始化
    bool isInit { get;  set; }
    void Init(Transform targetT, Transform cameraT)
    {
        if (false == isInit)
        {
            this.targetT = targetT;
            this.cameraT = cameraT;
            cameraT.position = targetT.position - (cameraT.rotation * Vector3.forward * distance);
            rot = cameraT.eulerAngles;
            isInit = true;
        }
    }
    #endregion




    void LateUpdate()
    {
        if (isInit==false || targetT ==null) return;

        var targetPos = targetT.position + offset;

        // rotation and zoom should only happen if not in a UI right now
        if (!IsCursorOverUserInterface())
        {
            // right mouse rotation if we have a mouse
            if (Input.mousePresent)
            {
                if (Input.GetMouseButtonDown(1))
                {
                    //Debug.Log ( "鼠标右键瞬间按下=" + Time.realtimeSinceStartup );
                    timer = Time.realtimeSinceStartup;
                    startRotate = false;
                }
                if (Input.GetMouseButton(1))
                {
                    // Debug.Log ( "鼠标右键按下中=" + Time.realtimeSinceStartup + "))result=" +( timer + time <= Time.realtimeSinceStartup?"true":"false ") );
                    if (timer + rightDownDuration <= Time.realtimeSinceStartup)
                    {
                        startRotate = true;
                    }
                }

                if (Input.GetMouseButton(mouseButton) && startRotate)
                {
                    // note: mouse x is for y rotation and vice versa
                    rot.y += Input.GetAxis("Mouse X") * rotationSpeed;
                    rot.x -= Input.GetAxis("Mouse Y") * rotationSpeed;
                    rot.x = Mathf.Clamp(rot.x, xMinAngle, xMaxAngle);
                    cameraT.rotation = Quaternion.Euler(rot.x, rot.y, 0);
                }
            }
            else
            {
                // forced 45 degree if there is no mouse to rotate (for mobile)
                cameraT.rotation = Quaternion.Euler(new Vector3(45, 0, 0));
            }

            // zoom
            float speed = Input.mousePresent ? zoomSpeedMouse : zoomSpeedTouch;
            float step = GetZoomUniversal() * speed;
            distance = Mathf.Clamp(distance - step, minDistance, maxDistance);
        }

        // target follow
        cameraT.position = targetPos - (cameraT.rotation * Vector3.forward * distance);

    }

    static float GetZoomUniversal()
    {
        if (Input.mousePresent)
            return GetAxisRawScrollUniversal();
        else if (Input.touchSupported)
            return GetPinch();
        return 0;
    }

    // two finger pinch detection
    // source: https://docs.unity3d.com/Manual/PlatformDependentCompilation.html
    static float GetPinch()
    {
        if (Input.touchCount == 2)
        {
            // Store both touches.
            Touch touchZero = Input.GetTouch(0);
            Touch touchOne = Input.GetTouch(1);

            // Find the position in the previous frame of each touch.
            Vector2 touchZeroPrevPos = touchZero.position - touchZero.deltaPosition;
            Vector2 touchOnePrevPos = touchOne.position - touchOne.deltaPosition;

            // Find the magnitude of the vector (the distance) between the touches in each frame.
            float prevTouchDeltaMag = (touchZeroPrevPos - touchOnePrevPos).magnitude;
            float touchDeltaMag = (touchZero.position - touchOne.position).magnitude;

            // Find the difference in the distances between each frame.
            return touchDeltaMag - prevTouchDeltaMag;
        }
        return 0;
    }

    static bool IsCursorOverUserInterface()
    {
         IsPointerOverGameObject check for left mouse (default)
        //if (EventSystem.current != null && EventSystem.current.IsPointerOverGameObject())
        //    return true;

         IsPointerOverGameObject check for touches
        //for (int i = 0; i < Input.touchCount; ++i)
        //    if (EventSystem.current != null && EventSystem.current.IsPointerOverGameObject(Input.GetTouch(i).fingerId))
        //        return true;

         OnGUI check
        //return GUIUtility.hotControl != 0;

        return false;
    }

    // hard mouse scrolling that is consistent between all platforms
    //   Input.GetAxis("Mouse ScrollWheel") and
    //   Input.GetAxisRaw("Mouse ScrollWheel")
    //   both return values like 0.01 on standalone and 0.5 on WebGL, which
    //   causes too fast zooming on WebGL etc.
    // normally GetAxisRaw should return -1,0,1, but it doesn't for scrolling
    static float GetAxisRawScrollUniversal()
    {
        float scroll = Input.GetAxisRaw("Mouse ScrollWheel");
        if (scroll < 0) return -1;
        if (scroll > 0) return 1;
        return 0;
    }
}


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Unity中实现摄像机跟随人物,可以使用以下两种方式: 1. 通过脚本控制摄像机位置和旋转 可以在摄像机上添加一个脚本,通过脚本代码实现摄像机跟随人物的效果。具体实现步骤如下: 1)获取人物的Transform组件,即人物的位置和旋转信息。 2)将摄像机的位置和旋转信息设置为人物的位置和旋转信息,可以通过Vector3.Lerp()方法实现平滑跟随。 3)在Update()方法中不断更新摄像机的位置和旋转信息,从而实现摄像机跟随效果。 示例代码: ``` public class CameraFollow : MonoBehaviour { public Transform target; // 人物的Transform组件 public float smoothTime = 0.3f; // 平滑跟随时间 private Vector3 velocity = Vector3.zero; void Update() { // 计算摄像机新的位置 Vector3 targetPosition = target.TransformPoint(new Vector3(0, 5, -10)); // 平滑跟随 transform.position = Vector3.SmoothDamp(transform.position, targetPosition, ref velocity, smoothTime); // 计算摄像机新的旋转角度 transform.LookAt(target); } } ``` 2. 使用Unity的跟随组件 Unity提供了一个跟随组件(Follow),可以通过简单的配置实现摄像机跟随人物的效果。具体实现步骤如下: 1)在摄像机上添加一个跟随组件(Component -> New Script -> Follow)。 2)将跟随组件的Target设置为人物的Transform组件。 3)调整跟随组件的其他参数,例如跟随速度、距离等。 示例代码: ``` using UnityEngine; using UnityStandardAssets.Utility; public class CameraFollow : MonoBehaviour { public Transform target; // 人物的Transform组件 public float distance = 10f; // 摄像机与人物的距离 public float height = 5f; // 摄像机与人物的高度 public float damping = 1f; // 跟随速度 private FollowTarget followTarget; void Start() { followTarget = GetComponent<FollowTarget>(); followTarget.target = target; followTarget.distance = distance; followTarget.height = height; followTarget.damping = damping; } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值