Hark-the-Moon-Men-Cometh / Assets / Vendor / Kevin Iglesias / Throwing Animations / Scripts / ThrowMultipleProps.cs
ThrowMultipleProps.cs
Raw
///////////////////////////////////////////////////////////////////////////
//  ThrowMultipleProps                                                   //
//  Kevin Iglesias - https://www.keviniglesias.com/       			     //
//  Contact Support: support@keviniglesias.com                           //
///////////////////////////////////////////////////////////////////////////

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace KevinIglesias {

    public class ThrowMultipleProps : MonoBehaviour {

        //Retargeters
        public Transform retargeter1;
        public Transform retargeter2;
    
        //Props to move
        public Transform propToThrow1;
        public Transform propToThrow2;
    
        //Hands that holds the props
        public Transform hand1;
        public Transform hand2;
    
        //Target to throw the prop
        public Transform targetPos;

        //Speed of the prop
        public float speed = 10;
        
        //Maximum arc the prop will make
        public float arcHeight = 1;
        
        //Needed for checking if prop was thrown or not
        public bool launched1 = false;
        public bool launched2 = false;
        public bool recoverProp1 = false;
        public bool recoverProp2 = false;
        
        //Needed for checking if prop landed
        public bool propLanded1 = false;
        public bool propLanded2 = false;
        
        //Character root (for parenting when prop is thrown)
        private Transform characterRoot;
        
        //Needed for calculate prop trajectory
        private Vector3 startPos1;
        private Vector3 startPos2;
        private Vector3 zeroPosition1;
        private Quaternion zeroRotation1;
        private Vector3 zeroPosition2;
        private Quaternion zeroRotation2;
        private Vector3 nextPos;
        
        void Start() {
            characterRoot = this.transform;
            
            zeroPosition1 = propToThrow1.localPosition;
            zeroRotation1 = propToThrow1.localRotation;
            zeroPosition2 = propToThrow2.localPosition;
            zeroRotation2 = propToThrow2.localRotation;
        }
        
        //This will make the prop move when launched
        void Update() 
        {
            //Arc throw prop 1
            if(launched1 && !propLanded1)
            {
                float x0 = startPos1.x;
                float x1 = targetPos.position.x;
                float dist = x1 - x0;
                float nextX = Mathf.MoveTowards(propToThrow1.position.x, x1, speed * Time.deltaTime);
                float baseY = Mathf.Lerp(startPos1.y, targetPos.position.y, (nextX - x0) / dist);
                float arc = arcHeight * (nextX - x0) * (nextX - x1) / (-0.25f * dist * dist);
                Vector3 nextPos = new Vector3(nextX, baseY + arc, propToThrow1.position.z);
            
                propToThrow1.rotation = LookAt2D(nextPos - propToThrow1.position);
                propToThrow1.position = nextPos;
                
                float currentDistance = Mathf.Abs(targetPos.position.x - propToThrow1.position.x);
                if(currentDistance < 0.5f)
                {
                    propLanded1 = true;
                }
    
            }
            
            //Arc throw prop 2
            if(launched2 && !propLanded2)
            {
                float x0 = startPos2.x;
                float x1 = targetPos.position.x;
                float dist = x1 - x0;
                float nextX = Mathf.MoveTowards(propToThrow2.position.x, x1, speed * Time.deltaTime);
                float baseY = Mathf.Lerp(startPos2.y, targetPos.position.y, (nextX - x0) / dist);
                float arc = arcHeight * (nextX - x0) * (nextX - x1) / (-0.25f * dist * dist);
                Vector3 nextPos = new Vector3(nextX, baseY + arc, propToThrow2.position.z);
            
                propToThrow2.rotation = LookAt2D(nextPos - propToThrow2.position);
                propToThrow2.position = nextPos;
                
                float currentDistance = Mathf.Abs(targetPos.position.x - propToThrow2.position.x);
                if(currentDistance < 0.5f)
                {
                    propLanded2 = true;
                }
     
            }
            
            if(retargeter1.localPosition.y > 0)
            {
                if(!launched1 && !recoverProp1)
                {
                    Throw1();
                }
                
                if(launched1 && recoverProp1)
                {
                    RecoverProp1();
                }
            }else{
                
                if(!recoverProp1 && launched1)
                {
                    recoverProp1 = true;
                }
                
                if(recoverProp1 && !launched1)
                {
                    recoverProp1 = false;
                }
            }
            
            if(retargeter2.localPosition.y > 0)
            {
                if(!launched2 && !recoverProp2)
                {
                    Throw2();
                }
                
                if(launched2 && recoverProp2)
                {
                    RecoverProp2();
                }
            }else{
                
                if(!recoverProp2 && launched2)
                {
                    recoverProp2 = true;
                }
                
                if(recoverProp2 && !launched2)
                {
                    recoverProp2 = false;
                }
            }
            
        }
        
        static Quaternion LookAt2D(Vector3 forward) {
            return Quaternion.Euler(0, 0, (Mathf.Atan2(forward.y, forward.x) * Mathf.Rad2Deg)-90);
        }   
        
       //Function called when retargeter1 is active
        public void Throw1()
        {
            startPos1 = propToThrow1.position;
            propToThrow1.SetParent(characterRoot);
            launched1 = true;
        }
        
        //Function called when retargeter2 is active
        public void Throw2()
        {
            startPos2 = propToThrow2.position;
            propToThrow2.SetParent(characterRoot);
            launched2 = true;
        }
        
        //Function called when retargeter1 is active
        public void RecoverProp1()
        {
            propLanded1 = false;
            launched1 = false;
            propToThrow1.SetParent(hand1);
            propToThrow1.localPosition = zeroPosition1;
            propToThrow1.localRotation = zeroRotation1;
        }
        
        //Function called when retargeter2 is active
        public void RecoverProp2()
        {
            propLanded2 = false;
            launched2 = false;
            propToThrow2.SetParent(hand2);
            propToThrow2.localPosition = zeroPosition2;
            propToThrow2.localRotation = zeroRotation2;
        }
    }

}