using System.Collections; using System.Collections.Generic; using GameKitController.Audio; using UnityEngine; using UnityEngine.Events; public class putObjectSystem : MonoBehaviour { public string objectName; public bool putObjectSystemEnabled = true; public bool ignoreTriggerEnterExitFunctionsEnabled; public bool useCertainObjectToPlace; public GameObject certainObjectToPlace; public string objectNameToPlace; public bool useObjectNameListToPlace; public List objectNameListToPlace = new List (); public Transform placeToPutObject; public GameObject currentObjectPlaced; public float placeObjectPositionSpeed; public float placeObjectRotationSpeed; public bool useRotationLimit; public float maxUpRotationAngle = 30; public float maxForwardRotationAngle = 30; public bool usePositionLimit; public float maxPositionDistance; public bool needsOtherObjectPlacedBefore; public int numberOfObjectsToPlaceBefore; public bool disableObjectOnceIsPlaced; public bool objectInsideTrigger; public bool objectPlaced; public bool waitToObjectPlacedToCallEvent; public objectToPlaceSystem currentObjectToPlaceSystem; public bool useLimitToCheckIfObjectRemoved; public float minDistanceToRemoveObject; public bool checkingIfObjectIsRemoved; public float minWaitToPutSameObjectAgain = 0.7f; public bool updateTriggerStateAfterWait; public UnityEvent objectPlacedEvent; public UnityEvent objectRemovedEvent; public bool useSoundEffectOnObjectPlaced; public AudioClip soundEffectOnObjectPlaced; public AudioElement onObjectPlacedAudioElement; public bool useSoundEffectOnObjectRemoved; public AudioClip soundEffectOnObjectRemoved; public AudioElement onObjectRemovedAudioElement; public AudioSource mainAudioSource; public Collider mainTrigger; public bool destroyObjectOncePlaced; public bool objectAdjustedToPlacePosition; Coroutine placeObjectCoroutine; int currentNumberObjectsPlaced; bool objectInCorrectPosition; bool objectInCorrectRotation; bool movingObject; float lastTimeObjectRemoved; GameObject lastObjectPlaced; Coroutine pauseCoroutine; bool cancelPlaceObjectActive; private void InitializeAudioElements () { if (mainAudioSource != null) { onObjectPlacedAudioElement.audioSource = mainAudioSource; onObjectRemovedAudioElement.audioSource = mainAudioSource; } if (soundEffectOnObjectPlaced != null) { onObjectPlacedAudioElement.clip = soundEffectOnObjectPlaced; } if (soundEffectOnObjectRemoved != null) { onObjectRemovedAudioElement.clip = soundEffectOnObjectRemoved; } } private void Start () { InitializeAudioElements (); } void Update () { if (objectInsideTrigger) { if (!objectPlaced) { if (useRotationLimit) { float forwardAngle = Vector3.SignedAngle (transform.forward, currentObjectPlaced.transform.forward, transform.up); float upAngle = Vector3.SignedAngle (transform.up, currentObjectPlaced.transform.up, transform.forward); if (Mathf.Abs (forwardAngle) > maxForwardRotationAngle || Mathf.Abs (upAngle) > maxUpRotationAngle) { objectInCorrectRotation = false; } else { objectInCorrectRotation = true; } } if (usePositionLimit) { float currentDistance = GKC_Utils.distance (currentObjectPlaced.transform.position, transform.position); if (currentDistance <= maxPositionDistance) { objectInCorrectPosition = true; } else { objectInCorrectPosition = false; } } if (useRotationLimit && !objectInCorrectRotation) { return; } if (usePositionLimit && !objectInCorrectPosition) { return; } checkIfCanBePlaced (false); } else { if (checkingIfObjectIsRemoved) { float currentDistance = GKC_Utils.distance (currentObjectPlaced.transform.position, placeToPutObject.position); if (currentDistance > minDistanceToRemoveObject) { removeObject (); } else { if (!currentObjectToPlaceSystem.isObjectInGrabbedState ()) { checkIfCanBePlaced (true); } } } if (destroyObjectOncePlaced) { if (objectAdjustedToPlacePosition) { GameObject objectToDestroy = currentObjectPlaced; removeObject (); if (objectToDestroy != null) { Destroy (objectToDestroy); } } } } } } public void destroyCurrentObjectPlaced () { if (objectAdjustedToPlacePosition) { GameObject objectToDestroy = currentObjectPlaced; removeObject (); if (objectToDestroy != null) { Destroy (objectToDestroy); } } } public void OnTriggerEnter (Collider col) { if (ignoreTriggerEnterExitFunctionsEnabled) { return; } checkTriggerInfo (true, col.gameObject); } public void OnTriggerExit (Collider col) { if (ignoreTriggerEnterExitFunctionsEnabled) { return; } checkTriggerInfo (false, col.gameObject); } public void checkTriggerInfo (bool isEnter, GameObject objectToCheck) { checkObjectToPlace (isEnter, objectToCheck); } public void placeObject (GameObject objectToCheck) { checkObjectToPlace (true, objectToCheck); } void checkObjectToPlace (bool isEnter, GameObject objectToCheck) { if (!putObjectSystemEnabled) { return; } if (isEnter) { if (!objectPlaced) { objectToCheck = canBeDragged (objectToCheck); if (objectToCheck != null) { if (objectToCheck == lastObjectPlaced && Time.time < lastTimeObjectRemoved + minWaitToPutSameObjectAgain) { if (updateTriggerStateAfterWait) { pausePutObject (); } //print ("same object to soon, pausing"); return; } currentObjectPlaced = objectToCheck; if (!useRotationLimit && !usePositionLimit) { checkIfCanBePlaced (false); } objectInsideTrigger = true; lastObjectPlaced = currentObjectPlaced; if (cancelPlaceObjectActive) { resetPlacedObjectValues (); } cancelPlaceObjectActive = false; } } } else { if (!objectPlaced) { objectToCheck = canBeDragged (objectToCheck); if (objectToCheck != null) { currentObjectPlaced = null; objectInsideTrigger = false; lastTimeObjectRemoved = Time.time; //print ("updating last time"); } } } } public void checkIfCanBePlaced (bool objectPlacedPreviously) { bool objectCanBePlaced = true; if (needsOtherObjectPlacedBefore) { if (numberOfObjectsToPlaceBefore != currentNumberObjectsPlaced) { objectCanBePlaced = false; } } if (objectCanBePlaced) { Rigidbody mainRigidbody = currentObjectPlaced.GetComponent (); if (mainRigidbody != null) { mainRigidbody.isKinematic = true; } moveObjectToPlace (objectPlacedPreviously); objectPlaced = true; checkingIfObjectIsRemoved = false; } } public GameObject canBeDragged (GameObject objectToCheck) { if (useCertainObjectToPlace) { if (objectToCheck == certainObjectToPlace || objectToCheck.transform.IsChildOf (certainObjectToPlace.transform)) { return objectToCheck; } } else { currentObjectToPlaceSystem = objectToCheck.GetComponent (); if (currentObjectToPlaceSystem != null) { if (useObjectNameListToPlace) { if (objectNameListToPlace.Contains (currentObjectToPlaceSystem.getObjectName ())) { return objectToCheck; } } else { if (objectNameToPlace == currentObjectToPlaceSystem.getObjectName ()) { return objectToCheck; } } } } return null; } public void moveObjectToPlace (bool objectPlacedPreviously) { stopMoveObjectToPlaceCoroutine (); stopPausePutObjectCoroutine (); placeObjectCoroutine = StartCoroutine (placeObjectIntoPosition (objectPlacedPreviously)); } public void stopMoveObjectToPlaceCoroutine () { if (placeObjectCoroutine != null) { StopCoroutine (placeObjectCoroutine); } } IEnumerator placeObjectIntoPosition (bool objectPlacedPreviously) { objectAdjustedToPlacePosition = false; grabbedObjectState currentGrabbedObject = currentObjectPlaced.GetComponent (); bool objectCanBePlaced = true; if (currentGrabbedObject != null) { objectCanBePlaced = GKC_Utils.checkIfObjectCanBePlaced (currentGrabbedObject.getCurrentHolder (), currentObjectPlaced); if (!objectCanBePlaced) { cancelPlaceObjectActive = true; } } currentObjectToPlaceSystem.setAdjustingObjectToPlaceInProcessState (true); if (objectCanBePlaced) { bool objectCanCallPlacedEvent = currentObjectToPlaceSystem.canObjectCanCallPlacedEvent (); if (!objectPlacedPreviously) { if (useSoundEffectOnObjectPlaced && objectCanCallPlacedEvent) { playSound (onObjectPlacedAudioElement); } } if (currentGrabbedObject != null) { GKC_Utils.dropObject (currentGrabbedObject.getCurrentHolder (), currentObjectPlaced); } Rigidbody mainRigidbody = currentObjectPlaced.GetComponent (); if (mainRigidbody != null) { mainRigidbody.isKinematic = true; } currentObjectToPlaceSystem.assignPutObjectSystem (this); currentObjectToPlaceSystem.setObjectPlaceState (true); currentObjectToPlaceSystem.checkEventOnObjectPlacedStateChanged (true); if (disableObjectOnceIsPlaced) { currentObjectToPlaceSystem.setObjectToPlacedEnabledState (false); grabPhysicalObjectSystem currentGrabPhysicalObjectSystem = currentObjectPlaced.GetComponent (); if (currentGrabPhysicalObjectSystem != null) { currentGrabPhysicalObjectSystem.disableGrabPhysicalObject (); } } if (!objectPlacedPreviously) { if (!waitToObjectPlacedToCallEvent && objectCanCallPlacedEvent) { bool checkEventResult = false; if (currentObjectToPlaceSystem.isUseSecondaryObjectToPlaceConnectedEnabled ()) { //if (currentObjectToPlaceSystem.isSecondaryObjectToPlaceConnected ()) { // checkEventResult = true; //} //if (currentObjectToPlaceSystem.isConnectedToOtherObjectToPlace () || // currentObjectToPlaceSystem.secondaryObjectToPlaceSystem.isConnectedToOtherObjectToPlace ()) { // checkEventResult = true; //} bool extremeConnectedResult = false; currentObjectToPlaceSystem.checkIfExtremeConnected (ref extremeConnectedResult, true, null); //print ("check extremeConnectedResult on object placed " + extremeConnectedResult); bool checkNameOnPutObjectSystemToCallEventResult = false; currentObjectToPlaceSystem.checkNameOnPutObjectSystemToCallEventResult (ref checkNameOnPutObjectSystemToCallEventResult, null); //print ("checkNameOnPutObjectSystemToCallEventResult " + checkNameOnPutObjectSystemToCallEventResult); if (extremeConnectedResult && checkNameOnPutObjectSystemToCallEventResult) { checkEventResult = true; } } else { checkEventResult = true; } if (checkEventResult) { checkEventsOnObjectPlacedOrRemoved (true); } } } currentObjectToPlaceSystem.checkStateOnExtremesOnObjectPlaced (); Transform objectTransform = currentObjectPlaced.transform; objectTransform.SetParent (placeToPutObject); Vector3 targetPosition = Vector3.zero; Quaternion targetRotation = Quaternion.identity; if (currentObjectToPlaceSystem.isUseCustomPlaceToPutObjectTransformActive ()) { Transform customPlaceToPutObjectTransform = currentObjectToPlaceSystem.getCustomPlaceToPutObjectTransform (); targetPosition = customPlaceToPutObjectTransform.localPosition; targetRotation = customPlaceToPutObjectTransform.localRotation; } float dist = GKC_Utils.distance (objectTransform.position, placeToPutObject.position); float duration = dist / placeObjectPositionSpeed; float t = 0; float timePassed = 0; float angleDifference = 0; float positionDifference = 0; bool targetReached = false; while (!targetReached) { t += Time.deltaTime / duration; objectTransform.localPosition = Vector3.MoveTowards (objectTransform.localPosition, targetPosition, t); objectTransform.localRotation = Quaternion.Lerp (objectTransform.localRotation, targetRotation, t); timePassed += Time.deltaTime; angleDifference = Quaternion.Angle (objectTransform.localRotation, targetRotation); positionDifference = GKC_Utils.distance (objectTransform.localPosition, targetPosition); if (timePassed > 3) { targetReached = true; } if (positionDifference < 0.01f && angleDifference < 0.2f) { targetReached = true; } yield return null; } if (!objectPlacedPreviously) { if (waitToObjectPlacedToCallEvent && objectCanCallPlacedEvent) { checkEventsOnObjectPlacedOrRemoved (false); } } } else { stopMoveObjectToPlaceCoroutine (); resetPlacedObjectValues (); } objectAdjustedToPlacePosition = true; currentObjectToPlaceSystem.setAdjustingObjectToPlaceInProcessState (false); } void resetPlacedObjectValues () { objectPlaced = false; currentObjectToPlaceSystem = null; currentObjectPlaced = null; objectInsideTrigger = false; checkingIfObjectIsRemoved = false; objectAdjustedToPlacePosition = false; } public void removePlacedObject () { if (useLimitToCheckIfObjectRemoved) { checkingIfObjectIsRemoved = true; } else { removeObject (); } } public void dropCurrentObjectPlaced (bool reactivateObjectToUseOnPlaceSystem) { if (!putObjectSystemEnabled) { return; } if (currentObjectToPlaceSystem == null) { return; } Rigidbody currentRigidbody = currentObjectPlaced.GetComponent (); if (reactivateObjectToUseOnPlaceSystem) { currentObjectToPlaceSystem.setObjectToPlacedEnabledState (true); currentObjectToPlaceSystem.setObjectPlaceState (false); currentObjectToPlaceSystem.checkEventOnObjectPlacedStateChanged (false); currentObjectToPlaceSystem.setAdjustingObjectToPlaceInProcessState (false); } grabPhysicalObjectSystem currentGrabPhysicalObjectSystem = currentObjectPlaced.GetComponent (); if (currentGrabPhysicalObjectSystem != null) { currentGrabPhysicalObjectSystem.setGrabObjectPhysicallyEnabledState (true); } removeObject (); if (currentRigidbody != null) { currentRigidbody.isKinematic = false; currentRigidbody.AddForce (placeToPutObject.forward * 10, ForceMode.Impulse); } } public void removeObject () { if (!putObjectSystemEnabled) { return; } if (currentObjectToPlaceSystem == null) { return; } bool objectCanCallRemovedEvent = currentObjectToPlaceSystem.canObjectCanCallRemovedEvent (); if (objectCanCallRemovedEvent && useSoundEffectOnObjectRemoved) { playSound (onObjectRemovedAudioElement); } stopMoveObjectToPlaceCoroutine (); objectPlaced = false; if (objectCanCallRemovedEvent) { objectRemovedEvent.Invoke (); } currentObjectToPlaceSystem = null; currentObjectPlaced.transform.SetParent (null); currentObjectPlaced = null; objectInsideTrigger = false; checkingIfObjectIsRemoved = false; objectAdjustedToPlacePosition = false; } public void checkEventsOnObjectPlacedOrRemoved (bool state) { //print ("checkEventsOnObjectPlacedOrRemoved " + state); if (state) { objectPlacedEvent.Invoke (); } else { objectRemovedEvent.Invoke (); } } public void disableObjectPlacedFromGrab () { if (currentObjectPlaced != null) { currentObjectPlaced.tag = "Untagged"; } } public void increaseNumberObjectsPlaced () { currentNumberObjectsPlaced++; } public void decreaseNumberObjectsPlaced () { currentNumberObjectsPlaced--; if (currentNumberObjectsPlaced < 0) { currentNumberObjectsPlaced = 0; } } public void resetNumberObjectsPlaced () { if (placeObjectCoroutine != null) { StopCoroutine (placeObjectCoroutine); } currentNumberObjectsPlaced = 0; objectPlaced = false; objectInsideTrigger = false; objectAdjustedToPlacePosition = false; } public void playSound (AudioElement soundToPlay) { if (soundToPlay != null) { AudioPlayer.PlayOneShot (soundToPlay, gameObject); } } public void pausePutObject () { stopPausePutObjectCoroutine (); pauseCoroutine = StartCoroutine (pausePutObjectCoroutine ()); } public void stopPausePutObjectCoroutine () { if (pauseCoroutine != null) { StopCoroutine (pauseCoroutine); } } IEnumerator pausePutObjectCoroutine () { yield return new WaitForSeconds (minWaitToPutSameObjectAgain); if (mainTrigger == null) { mainTrigger = GetComponent (); } if (mainTrigger != null) { mainTrigger.enabled = false; mainTrigger.enabled = true; } } public bool isPutObjectSystemEnabled () { return putObjectSystemEnabled; } public string getObjectName () { return objectName; } public Vector3 getPlaceToPutObjectPosition () { if (placeToPutObject != null) { return placeToPutObject.position; } return transform.position; } }