320 lines
9.7 KiB
C#
320 lines
9.7 KiB
C#
|
|
using System.Collections;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using UnityEngine;
|
|||
|
|
|
|||
|
|
public class throwObjectTrayectorySystem : MonoBehaviour
|
|||
|
|
{
|
|||
|
|
[Header ("Main Settings")]
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public bool throwObjectEnabled = true;
|
|||
|
|
|
|||
|
|
public LayerMask layerToCheckThrowObject;
|
|||
|
|
public float maxRaycastDistance = 30;
|
|||
|
|
|
|||
|
|
public bool useInfiniteRaycastDistance;
|
|||
|
|
|
|||
|
|
public bool useMaxDistanceWhenNoSurfaceFound;
|
|||
|
|
public float maxDistanceWhenNoSurfaceFound;
|
|||
|
|
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public Transform throwPosition;
|
|||
|
|
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public GameObject objectToThrow;
|
|||
|
|
|
|||
|
|
[Space]
|
|||
|
|
[Header ("Other Settings")]
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public bool addLaunchObjectComponent;
|
|||
|
|
public bool addGrabbedObjectStateComponent;
|
|||
|
|
|
|||
|
|
public bool rotateObjectTowardThrowDirection;
|
|||
|
|
|
|||
|
|
public bool checkIfLockedCameraActive;
|
|||
|
|
|
|||
|
|
public bool ignoreCollisionsWithPlayerEnabled = true;
|
|||
|
|
|
|||
|
|
[Space]
|
|||
|
|
[Header ("Custom Throw Direction Settings")]
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public bool throwInCustomTransformDirection;
|
|||
|
|
public Transform customTransformDirection;
|
|||
|
|
public float customThrowDirectionAmount = 400;
|
|||
|
|
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public bool useCustomThrowPosition;
|
|||
|
|
public bool useCustomThrowLocalPosition;
|
|||
|
|
public Vector3 customThrowPosition;
|
|||
|
|
public Vector3 customThrowRotation;
|
|||
|
|
|
|||
|
|
[Space]
|
|||
|
|
[Header ("Debug")]
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public bool showGizmo;
|
|||
|
|
|
|||
|
|
public GameObject currentObjectToThrow;
|
|||
|
|
public Vector3 currentThrowSpeed;
|
|||
|
|
|
|||
|
|
[Space]
|
|||
|
|
[Header ("Components")]
|
|||
|
|
[Space]
|
|||
|
|
|
|||
|
|
public playerCamera mainPlayerCamera;
|
|||
|
|
public GameObject playerControllerGameObject;
|
|||
|
|
public Transform targetPositionTransform;
|
|||
|
|
|
|||
|
|
public Transform playerCameraGameObject;
|
|||
|
|
public Transform mainCameraTransform;
|
|||
|
|
|
|||
|
|
public Collider playerCollider;
|
|||
|
|
|
|||
|
|
|
|||
|
|
Rigidbody newObjectToThrowRigidbody;
|
|||
|
|
|
|||
|
|
RaycastHit hit;
|
|||
|
|
|
|||
|
|
Vector3 currentTargetPosition;
|
|||
|
|
|
|||
|
|
Vector3 raycastDirection;
|
|||
|
|
Vector3 raycastOrigin;
|
|||
|
|
|
|||
|
|
Ray newRay;
|
|||
|
|
|
|||
|
|
|
|||
|
|
public void setCurrentObjectToThrow (GameObject newObject)
|
|||
|
|
{
|
|||
|
|
if (throwPosition == null) {
|
|||
|
|
throwPosition = transform;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
currentObjectToThrow = newObject;
|
|||
|
|
|
|||
|
|
currentObjectToThrow.transform.SetParent (throwPosition);
|
|||
|
|
|
|||
|
|
Vector3 objectPosition = throwPosition.position;
|
|||
|
|
|
|||
|
|
if (useCustomThrowPosition) {
|
|||
|
|
objectPosition = customThrowPosition;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (useCustomThrowLocalPosition) {
|
|||
|
|
currentObjectToThrow.transform.localPosition = objectPosition;
|
|||
|
|
currentObjectToThrow.transform.localRotation = Quaternion.Euler (customThrowRotation);
|
|||
|
|
} else {
|
|||
|
|
currentObjectToThrow.transform.position = objectPosition;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
currentObjectToThrow.SetActive (true);
|
|||
|
|
|
|||
|
|
newObjectToThrowRigidbody = currentObjectToThrow.GetComponent<Rigidbody> ();
|
|||
|
|
|
|||
|
|
if (newObjectToThrowRigidbody != null) {
|
|||
|
|
newObjectToThrowRigidbody.isKinematic = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (ignoreCollisionsWithPlayerEnabled) {
|
|||
|
|
if (playerCollider != null) {
|
|||
|
|
Component [] components = currentObjectToThrow.GetComponentsInChildren (typeof (Collider));
|
|||
|
|
|
|||
|
|
foreach (Collider child in components) {
|
|||
|
|
Physics.IgnoreCollision (playerCollider, child, true);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void instantiateObject ()
|
|||
|
|
{
|
|||
|
|
if (currentObjectToThrow == null) {
|
|||
|
|
if (throwPosition == null) {
|
|||
|
|
throwPosition = transform;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Vector3 objectPosition = throwPosition.position;
|
|||
|
|
Quaternion objectRotation = throwPosition.rotation;
|
|||
|
|
|
|||
|
|
if (useCustomThrowPosition) {
|
|||
|
|
objectPosition = customThrowPosition;
|
|||
|
|
objectRotation = Quaternion.Euler (customThrowRotation);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
GameObject newObjectToThrow = (GameObject)Instantiate (objectToThrow, objectPosition, objectRotation);
|
|||
|
|
|
|||
|
|
setCurrentObjectToThrow (newObjectToThrow);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void calculateThrowDirection ()
|
|||
|
|
{
|
|||
|
|
raycastDirection = mainCameraTransform.TransformDirection (Vector3.forward);
|
|||
|
|
|
|||
|
|
raycastOrigin = mainCameraTransform.position;
|
|||
|
|
|
|||
|
|
bool isPlayerMovingOn3dWorld = !mainPlayerCamera.is2_5ViewActive ();
|
|||
|
|
|
|||
|
|
if (checkIfLockedCameraActive) {
|
|||
|
|
if (mainPlayerCamera != null) {
|
|||
|
|
if (!mainPlayerCamera.isCameraTypeFree () && isPlayerMovingOn3dWorld) {
|
|||
|
|
newRay = mainPlayerCamera.getCameraRaycastDirection ();
|
|||
|
|
|
|||
|
|
raycastDirection = newRay.direction;
|
|||
|
|
|
|||
|
|
raycastOrigin = newRay.origin;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
currentTargetPosition = targetPositionTransform.position;
|
|||
|
|
|
|||
|
|
float currentRaycastDistance = maxRaycastDistance;
|
|||
|
|
|
|||
|
|
if (useInfiniteRaycastDistance) {
|
|||
|
|
currentRaycastDistance = Mathf.Infinity;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Physics.Raycast (raycastOrigin, raycastDirection, out hit, currentRaycastDistance, layerToCheckThrowObject)) {
|
|||
|
|
currentTargetPosition = hit.point;
|
|||
|
|
|
|||
|
|
if (hit.collider == playerCollider) {
|
|||
|
|
Vector3 newRaycastPosition = hit.point + raycastDirection * 0.2f;
|
|||
|
|
|
|||
|
|
if (Physics.Raycast (newRaycastPosition, raycastDirection, out hit, currentRaycastDistance, layerToCheckThrowObject)) {
|
|||
|
|
currentTargetPosition = hit.point;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
if (useMaxDistanceWhenNoSurfaceFound) {
|
|||
|
|
currentTargetPosition = raycastOrigin + raycastDirection * maxDistanceWhenNoSurfaceFound;
|
|||
|
|
|
|||
|
|
} else {
|
|||
|
|
if (Physics.Raycast (targetPositionTransform.position, raycastDirection, out hit, Mathf.Infinity, layerToCheckThrowObject)) {
|
|||
|
|
currentTargetPosition = hit.point;
|
|||
|
|
|
|||
|
|
if (hit.collider == playerCollider) {
|
|||
|
|
Vector3 newRaycastPosition = hit.point + raycastDirection * 0.2f;
|
|||
|
|
|
|||
|
|
if (Physics.Raycast (newRaycastPosition, raycastDirection, out hit, Mathf.Infinity, layerToCheckThrowObject)) {
|
|||
|
|
currentTargetPosition = hit.point;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (showGizmo) {
|
|||
|
|
Debug.DrawLine (raycastOrigin, currentTargetPosition, Color.black, 5);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void throwObject ()
|
|||
|
|
{
|
|||
|
|
if (throwPosition == null) {
|
|||
|
|
throwPosition = transform;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (currentObjectToThrow == null) {
|
|||
|
|
instantiateObject ();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (throwInCustomTransformDirection) {
|
|||
|
|
currentThrowSpeed = customTransformDirection.forward * customThrowDirectionAmount;
|
|||
|
|
} else {
|
|||
|
|
currentThrowSpeed = getParableSpeed (currentObjectToThrow.transform.position, currentTargetPosition);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (showGizmo) {
|
|||
|
|
Debug.DrawLine (currentObjectToThrow.transform.position, currentTargetPosition, Color.black, 5);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (rotateObjectTowardThrowDirection) {
|
|||
|
|
currentObjectToThrow.transform.LookAt (currentTargetPosition);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
currentObjectToThrow.transform.SetParent (null);
|
|||
|
|
|
|||
|
|
if (currentThrowSpeed == -Vector3.one) {
|
|||
|
|
currentThrowSpeed = currentObjectToThrow.transform.forward * 100;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (newObjectToThrowRigidbody != null) {
|
|||
|
|
newObjectToThrowRigidbody.isKinematic = false;
|
|||
|
|
|
|||
|
|
newObjectToThrowRigidbody.AddForce (currentThrowSpeed, ForceMode.VelocityChange);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (addLaunchObjectComponent) {
|
|||
|
|
launchedObjects currentLaunchedObjects = currentObjectToThrow.GetComponent<launchedObjects> ();
|
|||
|
|
|
|||
|
|
if (currentLaunchedObjects == null) {
|
|||
|
|
currentLaunchedObjects = currentObjectToThrow.AddComponent<launchedObjects> ();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
currentLaunchedObjects.setCurrentPlayer (playerControllerGameObject);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (addGrabbedObjectStateComponent) {
|
|||
|
|
applyDamage.checkGravityRoomForGrabbedObject (currentObjectToThrow, playerControllerGameObject);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
currentObjectToThrow = null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//calculate the speed applied to the launched projectile to make a parable according to a hit point
|
|||
|
|
Vector3 getParableSpeed (Vector3 origin, Vector3 target)
|
|||
|
|
{
|
|||
|
|
//get the distance between positions
|
|||
|
|
Vector3 toTarget = target - origin;
|
|||
|
|
Vector3 toTargetXZ = toTarget;
|
|||
|
|
|
|||
|
|
//remove the Y axis value
|
|||
|
|
toTargetXZ -= playerCameraGameObject.transform.InverseTransformDirection (toTargetXZ).y * playerCameraGameObject.transform.up;
|
|||
|
|
float y = playerCameraGameObject.transform.InverseTransformDirection (toTarget).y;
|
|||
|
|
float xz = toTargetXZ.magnitude;
|
|||
|
|
|
|||
|
|
//get the velocity accoring to distance ang gravity
|
|||
|
|
float t = GKC_Utils.distance (origin, target) / 20;
|
|||
|
|
float v0y = y / t + 0.5f * Physics.gravity.magnitude * t;
|
|||
|
|
float v0xz = xz / t;
|
|||
|
|
|
|||
|
|
//create result vector for calculated starting speeds
|
|||
|
|
Vector3 result = toTargetXZ.normalized;
|
|||
|
|
|
|||
|
|
//get direction of xz but with magnitude 1
|
|||
|
|
result *= v0xz;
|
|||
|
|
|
|||
|
|
// set magnitude of xz to v0xz (starting speed in xz plane), setting the local Y value
|
|||
|
|
result -= playerCameraGameObject.transform.InverseTransformDirection (result).y * playerCameraGameObject.transform.up;
|
|||
|
|
result += playerCameraGameObject.transform.up * v0y;
|
|||
|
|
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void inputThrowObject ()
|
|||
|
|
{
|
|||
|
|
if (throwObjectEnabled) {
|
|||
|
|
throwObject ();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void inputInstantiateObject ()
|
|||
|
|
{
|
|||
|
|
if (throwObjectEnabled) {
|
|||
|
|
instantiateObject ();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void inputCalculateThrowDirection ()
|
|||
|
|
{
|
|||
|
|
if (throwObjectEnabled) {
|
|||
|
|
calculateThrowDirection ();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|