mirror of
https://github.com/DerTyp7/defrain-shooter-unity.git
synced 2025-10-29 20:52:10 +01:00
@juliuse98 needs to fix when looking up the weapon gets to far away an the hands look strange. Tried to fix it a bit. Its no a little better but NOT completely fixed. USP has now a collider that is a trigger. When the weapon is clipping through the wall (befor that the collider should trigger and the player puts the weapon upright) ITS NOT WORKING but the structure is there... (All collider gets disabled when you pick up a weapon)
421 lines
16 KiB
C#
421 lines
16 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using Mirror;
|
|
|
|
public class ProcedualAnimationController : NetworkBehaviour
|
|
{
|
|
[Header("Hand Settings")]
|
|
[SerializeField] private Transform rightHandREF;
|
|
[SerializeField] private Transform leftHandREF;
|
|
[SerializeField] private Transform gunRightHandREF;
|
|
[SerializeField] private Transform gunLeftHandREF;
|
|
[SerializeField] private Vector3 defaultRightHandPosition = Vector3.zero;
|
|
[SerializeField] private Vector3 defaultLeftHandPosition = Vector3.zero;
|
|
|
|
|
|
[Header("Step Settings")]
|
|
[SerializeField] private float stepAmplitudeWalking;
|
|
[SerializeField] private float stepAmplitudeSprinting;
|
|
[SerializeField] private float stepFrequency;
|
|
private float checkDist = 0f;
|
|
private float stepDistance = 1;
|
|
private float stepSin;
|
|
float moveSoftStart = 0;
|
|
Vector3 lastPos = Vector3.zero;
|
|
float posCheckDistance = 0.01f;
|
|
float currentDist = 0;
|
|
|
|
|
|
float f = 0f;
|
|
|
|
[SerializeField] private PlayerController playerController;
|
|
|
|
|
|
|
|
|
|
[Header("GameObjects")]
|
|
[SerializeField] private float currentCameraRecoilX = 0f;
|
|
[SerializeField] private float currentCameraRecoilY = 0f;
|
|
[Header("GameObjects")]
|
|
[SerializeField] private GameObject gunHolder;
|
|
[SerializeField] private WeaponManager weaponManager;
|
|
|
|
|
|
[Header("General Settings")]
|
|
[SerializeField] bool positionRecoil = true;
|
|
[SerializeField] bool rotationRecoil = true;
|
|
|
|
[Header("Position Settings")]
|
|
[SerializeField] float positionMultX = 25f;
|
|
[SerializeField] float positionMultY = 25f;
|
|
[SerializeField] float positionMultZ = 25f;
|
|
|
|
[Header("Rotation Settings")]
|
|
[SerializeField] PlayerMouseLook playerMouseLook;
|
|
[SerializeField] float cameraRecoilX = 0.1f;
|
|
[SerializeField] float cameraRecoilY = 0.1f;
|
|
|
|
|
|
[SerializeField] bool rotX = true;
|
|
[SerializeField] float rotationMultX = 25f;
|
|
[SerializeField] float rotationOffsetX = 0.1f;
|
|
[SerializeField] bool rotY = true;
|
|
[SerializeField] float rotationMultY = 25f;
|
|
[SerializeField] bool rotZ = true;
|
|
[SerializeField] float rotationMultZ = 15f;
|
|
|
|
[Header("Swey Settings")]
|
|
[SerializeField] bool sideSwey = true;
|
|
[SerializeField] float sweyMultX = 15f;
|
|
[SerializeField] float sweyMultY = 15f;
|
|
[SerializeField] float sweyMultZ = 15f;
|
|
[SerializeField] float sweyWhileAim = 0.1f;
|
|
float swey = 0f;
|
|
|
|
[Header("External Settings")]
|
|
[SerializeField] const int externalPositionVectorsNum = 1;
|
|
private Vector3[] externalPositionVectors = new Vector3[externalPositionVectorsNum];
|
|
|
|
|
|
[SerializeField] float returnForce = 0.006f;
|
|
[SerializeField] float impulsForce = 0.025f;
|
|
[SerializeField] float maxRecoil = 0.1f;
|
|
|
|
private Animator gunAnimator;
|
|
[SerializeField] private Animator playerAnimator;
|
|
|
|
Vector3 startPos, startRot;
|
|
float recoilOffset = 0f;
|
|
float zOffset = 0f;
|
|
float zVelocity = 0f;
|
|
|
|
int recoilCounter = 0;
|
|
[Header("Switch Settings")]
|
|
[Range(0, 1)] public float switchVal = 0;
|
|
|
|
[Header("Aiming Settings")]
|
|
[SerializeField] float aimSpeed = 0.01f;
|
|
[Range(0, 1)] public float aimVal = 0;
|
|
[SerializeField] GameObject AimPoint;
|
|
[SerializeField] GameObject HoldPoint;
|
|
public bool isAiming = false;
|
|
|
|
[Header("Camera Shake Info")]
|
|
[SerializeField] bool cameraShakeActive = true;
|
|
[SerializeField] Camera objectToMove;
|
|
[SerializeField] float cameraShakeDuration = 1f;
|
|
[SerializeField] int nearDistance = 5;
|
|
[SerializeField] AnimationCurve nearCameraShakeCurve;
|
|
[SerializeField] int mediumDistance = 15;
|
|
[SerializeField] AnimationCurve mediumCameraShakeCurve;
|
|
[SerializeField] int farDistance = 25;
|
|
[SerializeField] AnimationCurve farCameraShakeCurve;
|
|
private AnimationCurve cameraShakeCurve;
|
|
|
|
Vector3[] positionMod = new Vector3[4];
|
|
public Quaternion[] rotationMod = new Quaternion[4];
|
|
|
|
public Transform GunRightHandREF { get => gunRightHandREF; set => gunRightHandREF = value; }
|
|
public Transform GunLeftHandREF { get => gunLeftHandREF; set => gunLeftHandREF = value; }
|
|
|
|
public void cameraShake(float distance) {
|
|
// If camera shake is not disabled
|
|
if (cameraShakeActive) {
|
|
// Start coroutine that shakes the camera
|
|
StartCoroutine(shaking(distance));
|
|
}
|
|
}
|
|
|
|
private IEnumerator shaking(float distance) {
|
|
float elapsedTime = 0f;
|
|
bool cameraShake = true;
|
|
// Getting right camera shake curve
|
|
if(distance < nearDistance) {
|
|
cameraShakeCurve = nearCameraShakeCurve; // high camera shake
|
|
//Debug.Log("NEAR EXPLOSION: " + distance);
|
|
} else if(distance < mediumDistance){
|
|
cameraShakeCurve = mediumCameraShakeCurve; // medium camera shake
|
|
//Debug.Log("MEDIUM EXPLOSION: " + distance);
|
|
} else if(distance < farDistance) {
|
|
cameraShakeCurve = farCameraShakeCurve; // little camera shake
|
|
//Debug.Log("FAR EXPLOSION: " + distance);
|
|
} else { // If distance is even further than far then no camera shake
|
|
cameraShake = false;
|
|
}
|
|
|
|
if (cameraShake) {
|
|
while (elapsedTime < cameraShakeDuration) {
|
|
// Time increment
|
|
elapsedTime += Time.deltaTime;
|
|
// Getting strength value from curve at current time
|
|
float strength = cameraShakeCurve.Evaluate(elapsedTime / cameraShakeDuration);
|
|
// Move object
|
|
objectToMove.transform.localPosition = objectToMove.transform.localPosition + Random.insideUnitSphere * strength;
|
|
// Wait
|
|
yield return new WaitForSeconds(Time.deltaTime);
|
|
}
|
|
}
|
|
|
|
yield return null;
|
|
}
|
|
|
|
public void walkAnimation()
|
|
{
|
|
playerAnimator.SetFloat("x", playerController.localVelocity.x / playerController.currentMaxSpeed);
|
|
playerAnimator.SetFloat("y", playerController.localVelocity.z / playerController.currentMaxSpeed);
|
|
}
|
|
|
|
public void handPositioning()
|
|
{
|
|
if (gunRightHandREF != null)
|
|
{
|
|
rightHandREF.position = gunRightHandREF.position;
|
|
rightHandREF.rotation = gunRightHandREF.rotation;
|
|
}
|
|
else
|
|
{
|
|
rightHandREF.position = defaultRightHandPosition;
|
|
}
|
|
if (GunLeftHandREF != null)
|
|
{
|
|
leftHandREF.position = GunLeftHandREF.position;
|
|
leftHandREF.rotation = GunLeftHandREF.rotation;
|
|
}
|
|
else
|
|
{
|
|
leftHandREF.position = defaultLeftHandPosition;
|
|
}
|
|
}
|
|
public void OnSwitchWeapon(GameObject currentWeapon)
|
|
{
|
|
if (isLocalPlayer) {
|
|
if(currentWeapon != null) {
|
|
gunHolder = currentWeapon;
|
|
gunAnimator = currentWeapon.GetComponent<Weapon>().WeaponAnimator;
|
|
gunAnimator.SetFloat("ShootSpeed", 1f / (60f / currentWeapon.GetComponent<Weapon>().Firerate));
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Recoil(float force)
|
|
{
|
|
if (isLocalPlayer)
|
|
{
|
|
//Play the animation
|
|
gunAnimator.Play("Shoot");
|
|
//Add force for the recoil
|
|
//currentCameraRecoilX -= weightedPerlinNoise(cameraRecoilX, 1f, Time.time, 1);
|
|
//playerMouseLook = Mathf.SmoothDamp(playerMouseLook.fullPitch, playerMouseLook.fullPitch - weightedPerlinNoise(cameraRecoilX, 1f, Time.time, 1),ref f,0.01f);
|
|
CmdRecoil();
|
|
}
|
|
}
|
|
[Command]
|
|
private void CmdRecoil()
|
|
{
|
|
recoilCounter++;
|
|
playerMouseLook.fullPitch -= weightedPerlinNoise(cameraRecoilX, 1f, Time.time, 1);
|
|
transform.Rotate(Vector3.up * weightedPerlinNoise(cameraRecoilY, 1f, Time.time, 1f, -0.5f));
|
|
}
|
|
[Command]
|
|
private void CmdAim(bool input)
|
|
{
|
|
if (input) isAiming = true;
|
|
else isAiming = false;
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (isLocalPlayer)
|
|
{
|
|
walkAnimation();
|
|
handPositioning();
|
|
CmdAim(Input.GetButton("Aim"));
|
|
}
|
|
/*-----Aiming-----*/
|
|
|
|
}
|
|
|
|
private void FixedUpdate()
|
|
{
|
|
if (isServer)
|
|
{
|
|
positionMod = new Vector3[4];
|
|
rotationMod = new Quaternion[4];
|
|
/*-----Recoil-----*/
|
|
calcRecoilOffset();
|
|
/*-----Position Recoil-----*/
|
|
PositionRecoil();
|
|
/*-----Rotation Recoil-----*/
|
|
RotationRecoil();
|
|
/*-----Step Swey-----*/
|
|
calcStepSin();
|
|
SideStep();
|
|
/*-----Aiming-----*/
|
|
AimDownSights();
|
|
/*-----Apply Gun Position-----*/
|
|
Vector3 totalPosition = Vector3.zero;
|
|
for (int i = 0; i < positionMod.Length; i++)
|
|
{
|
|
if (positionMod[i] != null)
|
|
totalPosition += positionMod[i];
|
|
//if (i == 3)
|
|
//Debug.Log(positionMod[i]);
|
|
}
|
|
|
|
/*-----Apply Gun Rotation-----*/
|
|
Quaternion totalRotation = Quaternion.identity;
|
|
for (int i = 0; i < rotationMod.Length; i++)
|
|
{
|
|
totalRotation *= rotationMod[i];
|
|
}
|
|
//gunHolder.transform.localPosition = positionMod[2];
|
|
gunHolder.transform.localPosition = totalPosition;
|
|
//gunHolder.transform.localRotation = totalRotation;
|
|
gunHolder.transform.localRotation = rotationMod[0];
|
|
}
|
|
}
|
|
|
|
void RotationRecoil()
|
|
{
|
|
/*-----Rotation Recoil-----*/
|
|
if (rotationRecoil)
|
|
{
|
|
float deltaX = 100f * rotationMultX * weightedPerlinNoise(recoilOffset, 0.5f, Time.time, 1f);
|
|
float deltaY = 100f * rotationMultY * weightedPerlinNoise(recoilOffset, 0.5f, Time.time, 1f, -0.5f);
|
|
float deltaZ = 100f * rotationMultZ * weightedPerlinNoise(recoilOffset, 0.5f, Time.time, 1f, -0.5f);
|
|
|
|
rotationMod[0] = Quaternion.Euler(deltaX, deltaY, deltaZ);
|
|
}
|
|
}
|
|
void PositionRecoil()
|
|
{
|
|
if (positionRecoil)
|
|
{
|
|
float deltaX = -positionMultX * weightedPerlinNoise(recoilOffset, 0.7f, Time.time, 1f, -0.5f);
|
|
float deltaY = -positionMultY * weightedPerlinNoise(recoilOffset, 0.5f, Time.time, 2f);
|
|
float deltaZ = positionMultZ * weightedPerlinNoise(recoilOffset, 0.5f, Time.time, 3f);
|
|
|
|
positionMod[0] = new Vector3(deltaX, deltaY, deltaZ);
|
|
}
|
|
}
|
|
void AimDownSights()
|
|
{
|
|
aimVal = gravityValue(aimVal, aimSpeed, 1, 0, isAiming);
|
|
positionMod[2] = Vector3.Lerp(HoldPoint.transform.localPosition, AimPoint.transform.localPosition, Mathf.Pow(aimVal, 1.3f));
|
|
}
|
|
public void weaponToCloseToWall(bool state) {
|
|
int lineNumber = (new System.Diagnostics.StackFrame(0, true)).GetFileLineNumber(); // Only for debugging
|
|
//Debug.Log("PAC.cs (function at line:" + (lineNumber-1) + "): Weapon is to close to wall: Weapon should get upright or to normal position now depending on state!");
|
|
}
|
|
public void changePistole(bool isSwitching) { // Moves hands doooown ;) and up again NOT WORKING
|
|
//aimVal = gravityValue(aimVal, aimSpeed, 1, 0, isSwitching);
|
|
Vector3 b = new Vector3(HoldPoint.transform.localPosition.x, 1, HoldPoint.transform.localPosition.z);
|
|
//Debug.Log("PositionMod[3]: " + positionMod[3]);
|
|
positionMod[3] = Vector3.Lerp(HoldPoint.transform.localPosition, b, 0.5f);
|
|
//Debug.Log("PositionMod[3]: " + positionMod[3]);
|
|
}
|
|
public void changeRifle(bool isSwitching) { // Moves hands up and doooown again ;)
|
|
//aimVal = gravityValue(aimVal, aimSpeed, 1, 0, isSwitching);
|
|
//Vector3 b = new Vector3(HoldPoint.transform.localPosition.x, HoldPoint.transform.localPosition.y + 1, HoldPoint.transform.localPosition.z);
|
|
//positionMod[3] = Vector3.Lerp(HoldPoint.transform.localPosition, b, 0);
|
|
//Debug.Log("HALLO2");
|
|
}
|
|
|
|
void calcRecoilOffset()
|
|
{
|
|
for (int i = 0; i < recoilCounter; i++)
|
|
{
|
|
zVelocity -= weightedPerlinNoise(impulsForce, 0.1f, i, 1f);
|
|
}
|
|
recoilCounter = 0;
|
|
|
|
recoilOffset += zVelocity;
|
|
|
|
zVelocity = 0;
|
|
|
|
if (recoilOffset > 0)
|
|
recoilOffset = 0f;
|
|
else if (recoilOffset < 0)
|
|
zVelocity += weightedPerlinNoise(returnForce, 0.1f, Time.time, 1f);
|
|
|
|
recoilOffset = Mathf.Clamp(recoilOffset, -weightedPerlinNoise(maxRecoil, 0.5f, Time.time * 1000, 1f), 0);
|
|
|
|
}
|
|
void calcStepSin()
|
|
{
|
|
float amplitude;
|
|
|
|
float dist = Vector3.Distance(lastPos, this.transform.position);
|
|
if (playerController.isSprinting)
|
|
amplitude = stepAmplitudeSprinting;
|
|
else
|
|
amplitude = stepAmplitudeWalking;
|
|
|
|
if (dist > posCheckDistance)
|
|
{
|
|
currentDist += dist;
|
|
lastPos = this.transform.position;
|
|
}
|
|
else
|
|
{
|
|
checkDist = currentDist + dist;
|
|
}
|
|
stepSin = ezSin(stepAmplitudeWalking, stepFrequency, currentDist);
|
|
}
|
|
void SideStep()
|
|
{
|
|
if (sideSwey)
|
|
{
|
|
//To start and end the sweying motion softly
|
|
|
|
moveSoftStart = gravityValue(moveSoftStart, 0.1f, 0.03f, 1f, 0f, playerController.isMoving() && playerController.isGrounded);
|
|
|
|
if (playerController.isMoving())
|
|
{
|
|
float deltaX = sweyMultX * moveSoftStart * Mathf.Clamp(Vector3.Magnitude(playerController.velocity), 0, 1) * weightedPerlinNoise(stepSin, 0.3f, Time.time, 10f, 0.5f) * Mathf.Clamp((1 - aimVal) * (1 - aimVal), sweyWhileAim, 1f);
|
|
float deltaY = sweyMultY * moveSoftStart * Mathf.Clamp(Vector3.Magnitude(playerController.velocity), 0, 1) * weightedPerlinNoise(stepSin, 0.7f, Time.time, 20f, -0.5f) * Mathf.Clamp((1 - aimVal) * (1 - aimVal), sweyWhileAim, 1f);
|
|
float deltaZ = sweyMultZ * moveSoftStart * Mathf.Clamp(Vector3.Magnitude(playerController.velocity), 0, 1) * weightedPerlinNoise(stepSin, 0.3f, Time.time, 30f, 0.5f) * Mathf.Clamp((1 - aimVal) * (1 - aimVal), sweyWhileAim, 1f);
|
|
|
|
positionMod[1] = new Vector3(deltaX, deltaY, deltaZ);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/*-----Helper Methods-----*/
|
|
float gravityValue(float curretnValue, float rateOfChange, float maxValue, float minValue, bool add)
|
|
{
|
|
// The currentValue will be advanced or reduced by the rateOfChange depending on the add boolean. But only in the specified range.
|
|
// Usage: val = gravityValue(val, 0.01f, 1, 0, true);
|
|
float value = curretnValue;
|
|
if (add) value += rateOfChange;
|
|
else value -= rateOfChange;
|
|
|
|
return Mathf.Clamp(value, minValue, maxValue);
|
|
}
|
|
float weightedPerlinNoise(float value, float weight, float pX, float pY, float offset = 0f)
|
|
{
|
|
return value * (1f - weight) + value * weight * (Mathf.PerlinNoise(pX, pY) + offset);
|
|
}
|
|
|
|
float gravityValue(float curretnValue, float rateOfChangePos, float rateOfChangeNeg, float maxValue, float minValue, bool add)
|
|
{
|
|
// The currentValue will be advanced by the rateOfChangePos and reduced by the rateOfChangeNeg depending on the add boolean. But only in the specified range.
|
|
// Usage: val = gravityValue(val, 0.01f, 0.05f, 1, 0, true);
|
|
float value = curretnValue;
|
|
if (add) value += rateOfChangePos;
|
|
else value -= rateOfChangeNeg;
|
|
|
|
return Mathf.Clamp(value, minValue, maxValue);
|
|
}
|
|
|
|
private float ezSin(float amplitude, float frequency, float x)
|
|
{
|
|
// Simplification of the sin function.
|
|
return amplitude * Mathf.Sin((x / 3.1831f) * 10 * frequency);
|
|
}
|
|
}
|