예제 #1
0
using UnityEngine;
using System.Collections;

namespace MFPP.Modules
{
    [HelpURL("https://ashkoredracson.github.io/MFPP/#pick-up-module")]

    [DisallowMultipleComponent]


    public class PickUpModule : PlayerModule
    {
        /// <summary>
        /// The maximum pickup distance.
        /// </summary>
        [Space]
        [Tooltip("The maximum pickup distance.")]
        public float MaxPickupDistance = 2f;
        public float breakDistance = 5f;
        public float maxVelocity = 12;

        [Tooltip("Pick up button.")]
        public string PickUpButton = "Pick Up";
        public Transform playerCam;
        public GameObject heldObject;
        public FootstepAsset originalFootstep;
        public FootstepAsset dragFootstep;
        public Rigidbody target;

        [SerializeField] private LayerMask newLayerMask;
        private Camera mainCamera;
        private float originalWalkingSpeed = 3;
        private IconContainer iconContainer;
        private AudioSource audioSource;
        private AudioClip pickupClip;
        private AudioClip dropClip;
        private AudioClip popClip;
        private float CurrentHeight;
        private float Radius;
        private IHoldable _holdable;
        private ISelectable _selectable;
        private ReticleObject _rObject;
        private RaycastManager rm;

        void Start () 
       {
            mainCamera = Camera.main;
            audioSource = GetComponent<AudioSource>();
            SoundBox sound = SoundBox.Instance;
            pickupClip = sound.pickup;
            popClip = sound.pop;
            dropClip = sound.deselect;
            iconContainer = Toolbox.Instance.GetIconContainer();
            CurrentHeight = GetComponent<MFPP.Player>().CurrentHeight;
            Radius = GetComponent<CharacterController>().radius;
            rm = GetComponent<RaycastManager>();
        }


        public override void AfterUpdate()
        {
            if (ControlManager.Instance.GetButtonDown("PickUp")) // If pick up button was pressed
            {
                if (target) // If we already have a target rigidbody, set it to null, thus dropping/throwing it.
                {PutDown();}
                else
                {PrepareForPickup();}
            }

            if (target) // If target is not null, move the target in front of the camera at max pickup distance.
            {
                bool check = CheckPlayerStance(target.gameObject);

                if (!check){
                    if (_holdable != null)
                    {
                        _holdable.HoldPosition();
                        //ObjectPositioning(type);
                    }
                }

                if (target && Vector3.Distance(this.transform.position, target.transform.position) >= breakDistance)
                {
                    PutDown();
                }

            }
        }

        public void PickUp (Rigidbody body) {
            //check if the object is already selected, remove it from list
            if (heldObject && _selectable != null)
            {
                rm.RemoveFromList(target.gameObject, true, false);
                rm.selectedObjs.Remove(target.gameObject);
            }

            target = body; // Set the target
            heldObject = target.gameObject;

            //have the object do the pickup changes!
            _holdable.DoPickup();
            //play sounds for pickup!
            Toolbox.Instance.SetVolume(audioSource);
            audioSource.clip = pickupClip;
            audioSource.Play();

        }

        public void PutDown () {

            //drop the object
            _holdable.Drop();
            _holdable = null;
            _selectable = null;
            _rObject = null;
            heldObject = null; //remove from the list
            target = null;

            //plays sound effect
            Toolbox.Instance.SetVolume(audioSource);
            audioSource.clip = dropClip;
            audioSource.Play();
        }

        private void PrepareForPickup()
        {
            if (this.gameObject.layer == 15) { newLayerMask.value = LayerMaskController.Laser; } //layermask value of layer 10 is 1024
            else if (this.gameObject.layer == 16) { newLayerMask.value = LayerMaskController.Real; } //layermask value of layer 11 is 2048

            Ray r = new Ray(mainCamera.transform.position, mainCamera.transform.forward);
            RaycastHit hit;

            if (Physics.Raycast(r, out hit, MaxPickupDistance, newLayerMask.value)) // Otherwise, if target was null, shoot a ray where we are aiming.
            {
                Rigidbody body = hit.collider.attachedRigidbody;

                _rObject = body.GetComponent<ReticleObject>();
                _holdable = _rObject as IHoldable;
                _selectable = _rObject as ISelectable;
                Transition transition = body.GetComponent<Transition>();

                //for picking up actual objects
                if  (_holdable != null && 
                     body &&
                     ((body.gameObject.layer + 5) == this.gameObject.layer)
                     && !CheckPlayerStance(body.gameObject)
                     && transition && !transition.GetTransitioning())
                        { PickUp(body); }
            }
        }


        public void KillPickup()
        {
            target = null;
            heldObject = null;
            _holdable = null;
            _selectable = null;
            _rObject = null;
        }

        private bool CheckPlayerStance(GameObject obj)
        {