Unity 2D,控制一个简单的镜头

时间:2018-01-17 16:29:57

标签: c# unity3d touch

我必须控制一个触球的球。一切正常,但是当我触摸屏幕时我需要开始我的轨迹,但是只有在触摸球时轨迹才会开始。是因为剧本附在球上了吗? 除了触球之外的所有触摸输入都被忽略。

这是C#脚本,有人可以帮帮我吗?

using UnityEngine;
using System.Collections;
using System;


namespace Shorka.BallTrajectory
{
    public enum PullState
    {
        Idle,
        UserPulling,
        ObjFlying
    }

    public class PullCtrl : MonoBehaviour
    {
        #region fields
        //[SerializeField] private Transform throwTarget;
        [SerializeField] private ThrownObject throwObj;

        [SerializeField] private Transform dotHelper;
        [SerializeField] private Transform pullingStartPoint;

        [Space(5)]
        [Tooltip("this linerenderer will draw the projected trajectory of the thrown object")]
        [SerializeField]
        private LineRenderer trajectoryLineRen;

        [SerializeField]
        private TrailMaker trail;

        [Space(5)]
        [SerializeField]
        private float throwSpeed = 10F;

        [Tooltip("Max Distance between 'PullingStartPoint' and pulling touch point")]
        [SerializeField]
        private float maxDistance = 1.5F;

        [SerializeField]
        private float coofDotHelper = 1.5F;

        [Tooltip("Related to length of trajectory line")]
        [SerializeField]
        private int qtyOfsegments = 13;

        [Tooltip("Step of changing trajectory dots offset in runtime")]
        [SerializeField]
        private float stepMatOffset = 0.01F;

        [Tooltip("Z position of trajectory dots")]
        [SerializeField]
        private float dotPosZ = 0F;

        private PullState pullState;
        private Camera camMain;
        //private Collider2D collThrowTarget;
        private Rigidbody2D rgThrowTarget;

        private Vector3 posPullingStart;
        private Vector3 initPos;

        private TrajectoryCtrl trajCtrl;
        #endregion

        public Vector3 PosDotHelper { get { return dotHelper.position; } }
        public Vector3 PosThrowTarget { get { return throwObj.transform.position; } }

        public int QtyOfsegments { get { return qtyOfsegments; } }
        public float DotPosZ { get { return dotPosZ; } }
        public Vector3 PosPullingStart { get { return posPullingStart; } }
        public float StepMatOffset { get { return stepMatOffset; } }



        void Awake()
        {
            trail.emit = false;
            trajCtrl = new TrajectoryCtrl(this, trajectoryLineRen);
        }

        void Start()
        {
            camMain = Camera.main;
            pullState = PullState.Idle;
            posPullingStart = pullingStartPoint.position;
            initPos = PosThrowTarget;

        }

        void Update()
        {
            SwitchStates();

        }

        private void SwitchStates()
        {
            switch (pullState)
            {
                case PullState.Idle:

                    if (Input.touchCount> 0 && Input.GetTouch(0).phase == TouchPhase.Began)
                    {


                        Debug.Log("Screen touched");
                        //get the point on screen user has tapped
                        Vector3 location = camMain.ScreenToWorldPoint(Input.GetTouch(0).position);
                        //if user has tapped onto the ball

                        if (throwObj.Collider == Physics2D.OverlapPoint(location))
                            pullState = PullState.UserPulling;
                    }
                    break;


                case PullState.UserPulling:

                    dotHelper.gameObject.SetActive(true);


                    if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved)
                    {


                        //get touch position
                        Vector3 touchPos = camMain.ScreenToWorldPoint(Input.GetTouch(0).position);
                        touchPos.z = 0;
                        //we will let the user pull the ball up to a maximum distance
                        if (Vector3.Distance(touchPos, posPullingStart) > maxDistance)
                        {
                            Vector3 maxPosition = (touchPos - posPullingStart).normalized * maxDistance + posPullingStart;
                            maxPosition.z = dotHelper.position.z;
                            dotHelper.position = maxPosition;
                        }
                        else
                        {
                            touchPos.z = dotHelper.position.z;
                            dotHelper.position = touchPos;
                        }

                        float distance = Vector3.Distance(posPullingStart, dotHelper.position);
                        trajCtrl.DisplayTrajectory(distance);
                    }
                    else if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Canceled || Input.GetTouch(0).phase == TouchPhase.Ended)
                    {
                        float distance = Vector3.Distance(posPullingStart, dotHelper.position);
                        trajectoryLineRen.enabled = false;
                        ThrowObj(distance);
                    }
                    break;

                default:
                    break;
            }
        }


        //private Vector2 velocityToRg = Vector2.zero;
        private void ThrowObj(float distance)
        {
            Debug.Log("ThrowObj");

            pullState = PullState.Idle;
            Vector3 velocity = posPullingStart - dotHelper.position;
            //velocityToRg = CalcVelocity(velocity, distance);

            throwObj.ThrowObj(CalcVelocity(velocity, distance));
            //rgThrowTarget.velocity = velocityToRg;
            //rgThrowTarget.isKinematic = false;

            trail.enabled = true;
            trail.emit = true;
            dotHelper.gameObject.SetActive(false);
        }


        public void Restart(Vector3 posThrownObj)
        {
            trail.emit = false;
            trail.Clear();

            StartCoroutine(ClearTrail());

            trajectoryLineRen.enabled = false;
            dotHelper.gameObject.SetActive(false);
            pullState = PullState.Idle;

            throwObj.Reset(posThrownObj);
        }

        private readonly WaitForSeconds wtTimeBeforeClear = new WaitForSeconds(0.3F);
        IEnumerator ClearTrail()
        {
            yield return wtTimeBeforeClear;
            trail.Clear();
            trail.enabled = false;
        }

        Vector3 velocity = Vector3.zero;
        public Vector3 CalcVelocity(Vector3 diff, float distance)
        {
            velocity.x = diff.x * throwSpeed * distance * coofDotHelper;
            velocity.y = diff.y * throwSpeed * distance * coofDotHelper;

            return velocity;
        }


    }


}

1 个答案:

答案 0 :(得分:0)

很容易。你需要将这两个脚本添加到游戏对象中(不是球,而是用于射击球的方式,如枪)

  

TouchEventTrigger.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;

public class TouchEventTrigger : MonoBehaviour, IPointerClickHandler,   IPointerDownHandler, IPointerUpHandler {
public TouchEvent onClick;
public TouchEvent onDown;
public TouchEvent onUp;

public void OnPointerClick(PointerEventData e) {
    onClick.Invoke(e);
}

public void OnPointerDown(PointerEventData e) {
    onDown.Invoke(e);
}

public void OnPointerUp(PointerEventData e) {
    onUp.Invoke(e);
}
}

[System.Serializable]
public class TouchEvent : UnityEvent<PointerEventData> {}
  

Shooter.cs

public void TryBeginAim(PointerEventData e) {
    if(canShoot) {
        initialTouchPos = e.position;
    }
}

public void TryAim(PointerEventData e) {
    if(canShoot) {
        direction = initialTouchPos - e.position;
        float mag = (initialTouchPos - e.position).magnitude;
        float scale = Mathf.Clamp(mag/maxMagnitude, scaleThreshold, 1f);
        angle = Mathf.Atan2(direction.y,direction.x) * Mathf.Rad2Deg + 90f; 

        aim.transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);


        aim.transform.localScale = Vector3.one * scale;
        aim.SetActive(e.position.y < initialTouchPos.y);
    }
}

public void TryShoot(PointerEventData e) {
    if(canShoot && aim.activeInHierarchy) {
        canShoot = false;
        StartCoroutine(ShootRoutine(balls));
    }

    aim.SetActive(false);
}

private IEnumerator ShootRoutine(int b) {
    // write code to start shooting balls.
}

然后使用以下方法连接触摸事件:
1. OnPointerClick =&gt; TryBeginAim
2. OnPointerDown =&gt; TryAim
3. OnPointerUp =&gt; TryShoot

全部!! 我希望这有助于解决这个问题。享受!