You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			168 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C#
		
	
			
		
		
	
	
			168 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C#
		
	
using System.Collections;
 | 
						|
using System.Collections.Generic;
 | 
						|
using UnityEngine;
 | 
						|
using UnityEngine.Events;
 | 
						|
 | 
						|
namespace Autohand{
 | 
						|
 | 
						|
[System.Serializable]
 | 
						|
public struct StepEvent {
 | 
						|
    public int step;
 | 
						|
    public UnityEvent OnStepEnter;
 | 
						|
    public UnityEvent OnStepExit;
 | 
						|
}
 | 
						|
 | 
						|
public class PhysicsGadgetLever : PhysicsGadgetHingeAngleReader{
 | 
						|
    [Min(0.01f), Tooltip("The percentage (0-1) from the required value needed to call the event, if threshold is 0.1 OnMax will be called at 0.9, OnMin at -0.9, and OnMiddle at -0.1 or 0.1")]
 | 
						|
    public float threshold = 0.05f;
 | 
						|
 | 
						|
    [Min(0)]
 | 
						|
    public int stepCount = 0;
 | 
						|
    public int startStep = 0;
 | 
						|
    private int prevStepCount = -1;
 | 
						|
 | 
						|
    public UnityEvent OnMax;
 | 
						|
    public UnityEvent OnMid;
 | 
						|
    public UnityEvent OnMin;
 | 
						|
    public StepEvent[] stepEvents;
 | 
						|
        
 | 
						|
    bool min = false;
 | 
						|
    bool max = false;
 | 
						|
    bool mid = true;
 | 
						|
 | 
						|
    private int currStep = -1;
 | 
						|
    private int prevStep = -1;
 | 
						|
    
 | 
						|
    private float minimum;
 | 
						|
    private float maximum;
 | 
						|
    float[] stepMarkers;
 | 
						|
 | 
						|
    protected void FixedUpdate(){
 | 
						|
        var value = GetValue();
 | 
						|
 | 
						|
        if(!max && mid && value+threshold >= 1) {
 | 
						|
            Max();
 | 
						|
        }
 | 
						|
 | 
						|
        if(!min && mid && value-threshold <= -1){
 | 
						|
            Min();
 | 
						|
        }
 | 
						|
        
 | 
						|
        if (value <= threshold && max && !mid) {
 | 
						|
            Mid();
 | 
						|
        }
 | 
						|
 | 
						|
        if (value >= -threshold && min && !mid) {
 | 
						|
            Mid();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    protected override void Start() {
 | 
						|
        base.Start();
 | 
						|
        if(startStep <= 0) return;
 | 
						|
 | 
						|
        FindSteps();
 | 
						|
        SetSpring(startStep - 1);
 | 
						|
    }
 | 
						|
 | 
						|
    void Update() {
 | 
						|
        AdjustStep();
 | 
						|
    }
 | 
						|
 | 
						|
    void AdjustStep() {
 | 
						|
        if(stepCount <= 0) return;
 | 
						|
 | 
						|
        FindSteps();
 | 
						|
        SetSpring(FindCurrentStep()); 
 | 
						|
    }
 | 
						|
 | 
						|
    bool FindSteps() {
 | 
						|
        if(prevStepCount == stepCount) return false;
 | 
						|
 | 
						|
        prevStepCount = stepCount;
 | 
						|
 | 
						|
        stepMarkers = new float[stepCount];
 | 
						|
 | 
						|
        minimum = GetJoint().limits.min;
 | 
						|
        maximum = GetJoint().limits.max;
 | 
						|
        
 | 
						|
        float step = GetStep();
 | 
						|
 | 
						|
        for(int i = 0; i < stepCount; i++) {
 | 
						|
            stepMarkers[stepCount - i - 1] = minimum + (i * step);
 | 
						|
        }
 | 
						|
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
 | 
						|
    public void SetSpring(int step)
 | 
						|
    {
 | 
						|
        GetJoint().transform.localRotation *= Quaternion.Euler(GetJoint().axis  * stepMarkers[step]);
 | 
						|
 | 
						|
        currStep = step;
 | 
						|
        JointSpring jointSpring = GetJoint().spring;
 | 
						|
        jointSpring.targetPosition = stepMarkers[step]; 
 | 
						|
        GetJoint().spring = jointSpring;
 | 
						|
    }
 | 
						|
 | 
						|
    public void SetSpring(float stepRotation)
 | 
						|
    {
 | 
						|
        JointSpring jointSpring = GetJoint().spring;
 | 
						|
        jointSpring.targetPosition = stepRotation; 
 | 
						|
        GetJoint().spring = jointSpring;
 | 
						|
    }
 | 
						|
 | 
						|
    float FindCurrentStep() {
 | 
						|
        float checkValue = GetValue() * GetRange();
 | 
						|
        for(int i = 0; i < stepCount; i++) {
 | 
						|
            if(checkValue >= GetMinimumStep(i) && checkValue <= GetMaximumStep(i)) {
 | 
						|
                currStep = i;
 | 
						|
                if(currStep != prevStep) {
 | 
						|
                    Step();
 | 
						|
                    prevStep = currStep;
 | 
						|
                }
 | 
						|
 | 
						|
                return stepMarkers[i];
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    float GetStep() => (Mathf.Abs(minimum) + Mathf.Abs(maximum)) / (stepCount - 1);
 | 
						|
    float GetRange() => (Mathf.Abs(minimum) + Mathf.Abs(maximum)) / 2;
 | 
						|
    float GetMinimumStep(int index) => stepMarkers[index] - (GetStep() / 2);
 | 
						|
    float GetMaximumStep(int index) => stepMarkers[index] + (GetStep() / 2);
 | 
						|
 | 
						|
    void Max() {
 | 
						|
        mid = false;
 | 
						|
        max = true;
 | 
						|
        OnMax?.Invoke();
 | 
						|
    }
 | 
						|
 | 
						|
    void Mid() {
 | 
						|
        min = false;
 | 
						|
        max = false;
 | 
						|
        mid = true;
 | 
						|
        OnMid?.Invoke();
 | 
						|
    }
 | 
						|
 | 
						|
    void Min() {
 | 
						|
        min = true;
 | 
						|
        mid = false;
 | 
						|
        OnMin?.Invoke();
 | 
						|
    }
 | 
						|
 | 
						|
    void Step() {
 | 
						|
        for(int i = 0; i < stepEvents.Length; i++) {
 | 
						|
            if(stepEvents[i].step == currStep + 1) {
 | 
						|
                stepEvents[i].OnStepEnter?.Invoke();
 | 
						|
            }
 | 
						|
            else if(stepEvents[i].step == prevStep + 1) {
 | 
						|
                stepEvents[i].OnStepExit?.Invoke();
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
}
 |