- Introduce `0Friction` and `100Friction` physics materials for improved control over object interactions. - Update `SampleScene` with modified Rigidbody and physics properties, including mass, damping, and material assignments. - Replace outdated mesh references and add new `CapsuleCollider` for the `Pump` object. - Adjust object layers, transforms, and configurable joint parameters for enhanced physics behavior.
201 lines
5.3 KiB
C#
201 lines
5.3 KiB
C#
using System;
|
|
using System.Collections;
|
|
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
using UnityEngine.Serialization;
|
|
|
|
public class TestScript2 : MonoBehaviour
|
|
{
|
|
private Rigidbody _rigidbody;
|
|
private InputAction _moveAction;
|
|
private InputAction _jumpAction;
|
|
|
|
private ConfigurableJoint _configurableJoint;
|
|
|
|
private float _smoothX;
|
|
private float _initDamping;
|
|
|
|
// max is 0.63
|
|
// min is 0.15
|
|
|
|
private JointDrive _jointDrive;
|
|
private JointDrive _softJointDrive;
|
|
|
|
private double _maxDifference = 0;
|
|
private double _initDifference = 0;
|
|
|
|
private bool _grounded = false;
|
|
private bool _jumpQueued = false;
|
|
private bool _jumped = false;
|
|
private bool _upJumpQueued = false;
|
|
private bool _canJump = false;
|
|
private bool _jumpInputBuffer = false;
|
|
|
|
private double? _previousDifference = null;
|
|
|
|
[SerializeField]
|
|
private float torqueForce;
|
|
|
|
[SerializeField]
|
|
private float lerpSpeed;
|
|
|
|
[SerializeField]
|
|
private float jumpDownForce = 1f;
|
|
|
|
[SerializeField]
|
|
private float jumpUpForce = 1f;
|
|
|
|
[SerializeField]
|
|
private float softPositionSpring = 200;
|
|
|
|
[SerializeField]
|
|
private ForceMode forceMode = ForceMode.Impulse;
|
|
|
|
[SerializeField]
|
|
private Rigidbody pump;
|
|
|
|
[SerializeField]
|
|
private DebugUi debugUi;
|
|
|
|
[SerializeField]
|
|
private float timeScale = 1f;
|
|
|
|
[SerializeField]
|
|
private bool lerp = true;
|
|
|
|
[SerializeField]
|
|
private LayerMask layerMask;
|
|
|
|
|
|
private void Awake()
|
|
{
|
|
_rigidbody = GetComponent<Rigidbody>();
|
|
_configurableJoint = GetComponent<ConfigurableJoint>();
|
|
|
|
_jointDrive = _configurableJoint.yDrive;
|
|
|
|
_initDamping = _rigidbody.angularDamping;
|
|
|
|
_softJointDrive = new JointDrive {
|
|
positionSpring = softPositionSpring,
|
|
maximumForce = _jointDrive.maximumForce,
|
|
positionDamper = _jointDrive.positionDamper,
|
|
useAcceleration = _jointDrive.useAcceleration
|
|
};
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
_moveAction = InputSystem.actions.FindAction("Move");
|
|
_jumpAction = InputSystem.actions.FindAction("Jump");
|
|
|
|
_moveAction.Enable();
|
|
_jumpAction.Enable();
|
|
|
|
_maxDifference = GetDifference();
|
|
_initDifference = _maxDifference;
|
|
debugUi?.UpdateText($"Difference: {_maxDifference}");
|
|
|
|
_initDamping = _rigidbody.angularDamping;
|
|
|
|
Time.timeScale = timeScale;
|
|
}
|
|
|
|
private double GetDifference()
|
|
{
|
|
Vector3 axis = transform.up; // this transform's local Y in world space
|
|
Vector3 toOther = pump.transform.position - transform.position;
|
|
|
|
var val = Vector3.Dot(toOther, axis);
|
|
|
|
val = Mathf.Abs(val);
|
|
|
|
return Math.Round(val, 2); // signed distance along local Y
|
|
}
|
|
|
|
private void Jump()
|
|
{
|
|
|
|
float t = Mathf.InverseLerp(0.15f, 0.63f, (float)_maxDifference); // gives 0 when 0.63, 1 when 0.15
|
|
float forceMultiplier = Mathf.Lerp(30, 5, t);
|
|
|
|
_maxDifference = _initDifference;
|
|
_previousDifference = null;
|
|
_jumpQueued = false;
|
|
_canJump = false;
|
|
_jumped = true;
|
|
|
|
pump.AddForce(transform.up * (jumpUpForce * forceMultiplier), ForceMode.Impulse);
|
|
_configurableJoint.yDrive = _jointDrive;
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
var moveValue = _moveAction.ReadValue<Vector2>();
|
|
|
|
if (moveValue.x != 0) {
|
|
_smoothX = lerp ? Mathf.Lerp(_smoothX, moveValue.x, Time.deltaTime * lerpSpeed) : moveValue.x;
|
|
} else {
|
|
_smoothX = 0;
|
|
}
|
|
|
|
debugUi?.UpdateGrounded(_grounded ? "Grounded" : "Not Grounded");
|
|
|
|
if ((_jumped && !_grounded) || _jumpAction.WasReleasedThisFrame()) {
|
|
_jumped = false;
|
|
}
|
|
|
|
if (_jumpAction.IsPressed() && _grounded && !_jumped) {
|
|
_jumpQueued = true;
|
|
}
|
|
|
|
if (_jumpQueued) {
|
|
|
|
if (GetDifference() < _maxDifference) {
|
|
_maxDifference = GetDifference();
|
|
}
|
|
|
|
_previousDifference ??= GetDifference();
|
|
|
|
if (_previousDifference < GetDifference() || _canJump) {
|
|
_canJump = true;
|
|
} else {
|
|
_previousDifference = GetDifference();
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
IEnumerator JumpInputBuffer()
|
|
{
|
|
yield return new WaitForSeconds(0.2f);
|
|
_jumpInputBuffer = false;
|
|
}
|
|
|
|
private void FixedUpdate()
|
|
{
|
|
// inverted to apply correct direction
|
|
_rigidbody.AddTorque(new Vector3(0, 0, -_smoothX) * torqueForce, forceMode);
|
|
|
|
if (_jumpQueued) {
|
|
_rigidbody.AddForce(-transform.up * jumpDownForce, ForceMode.Impulse);
|
|
|
|
if (_canJump) {
|
|
Jump();
|
|
}
|
|
}
|
|
|
|
var origin = pump.position;
|
|
var dir = -pump.transform.up; // world down
|
|
const float distance = .35f;
|
|
|
|
if (Physics.Raycast(origin, dir, out var hit, distance, layerMask.value)) {
|
|
Debug.DrawRay(origin, dir * hit.distance, Color.yellow);
|
|
_grounded = true;
|
|
} else {
|
|
Debug.DrawRay(origin, dir * distance, Color.white);
|
|
_grounded = false;
|
|
}
|
|
}
|
|
}
|