Sliding crane

This commit is contained in:
nothke 2024-08-17 13:38:26 +02:00
parent 87a0195f91
commit 0d1c168736
9 changed files with 1548 additions and 2 deletions

View File

@ -66,7 +66,7 @@ Material:
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _Glossiness: 0
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
@ -78,6 +78,6 @@ Material:
- _UVSec: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 0.988124, g: 1, b: 0, a: 1}
- _Color: {r: 1, g: 0.8835205, b: 0, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
m_BuildTextureStacks: []

View File

@ -0,0 +1,83 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: box_black
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 0.061, y: 0.061}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 2800000, guid: 4e76002f02c7e8c4290fb7bf8cb0fdc1, type: 3}
m_Scale: {x: 0.061, y: 0.061}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _BumpScale: 1
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 0.33962262, g: 0.33962262, b: 0.33962262, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
m_BuildTextureStacks: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 54361f89cfee8b94d810c14a6beb11b5
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
using Nothke.Utils;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SlidingCrane : MonoBehaviour
{
public InertialInterpolator xMotion = InertialInterpolator.Default();
public InertialInterpolator yMotion = InertialInterpolator.Default();
public Transform xTransform;
public Transform yTransform;
public float yRange = 10;
public float xRange = 5;
void Start()
{
yMotion.AccelerateTo(1);
xMotion.AccelerateTo(1);
}
// Update is called once per frame
void Update()
{
xMotion.Update(Time.deltaTime);
yMotion.Update(Time.deltaTime);
yTransform.localPosition = new Vector3(0, 0, yMotion.progress * yRange);
xTransform.localPosition = new Vector3(xMotion.progress * xRange, 0, 0);
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: da3ed29216d73fb43be6448aea116576
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6c0aa3bf4c555da4db98db8126dbda0c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,406 @@
///
/// Interpolator and InertialInterpolator by Nothke
///
/// A utility struct for when a value needs to smoothly transition between 2 states.
///
/// Call Regress() to make the state advance towards 0,
/// or Progress() to make it advance towards 1.
/// Alternatively use Toggle().
/// SetTo(value) will set it to a state immediately.
///
/// Call Update() every frame or fixed frame for the transition to progress.
///
/// An Interpolator is a version that transits at fixed speed.
///
/// An InertialInterpolator is a version that uses inertia, it will accelerate from one state,
/// and slow down when approaching the end state.
/// InertialInterpolator can also advance to arbitrary point with AccelerateTo(value).
/// It can also "emergency-stop" by calling StartBraking().
///
/// It doesn't matter if you call the functions repeatedly or once.
///
/// Make sure to have a maxSpeed parameter higher than 0, otherwise they won't move.
///
/// To initialize the struct correctly in inspector (with maxSpeed > 0) use:
/// public Interpolator interpolator = Interpolator.Default();
///
/// ============================================================================
///
/// MIT License
///
/// Copyright(c) 2021 Ivan Notaroš
///
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in all
/// copies or substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
/// SOFTWARE.
///
/// ============================================================================
///
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace Nothke.Utils
{
public enum ProgressionState
{
AtStart,
Progressing,
AtEnd,
Regressing
};
public interface IInterpolator
{
void Update(float dt);
ProgressionState State { get; }
/// <summary>
/// Advance value towards 1.
/// </summary>
void Progress();
/// <summary>
/// Advance value towards 0.
/// </summary>
void Regress();
void SetTo(float value);
/// <summary>
/// Toggle progression between progressing or regressing.
/// </summary>
void Toggle();
}
[System.Serializable]
public struct Interpolator : IInterpolator
{
public float maxSpeed;
[HideInInspector]
public float progress, velocity;
ProgressionState state;
public ProgressionState State => state;
//public bool ProgressingOrAtEnd => state == DeploymentState.Progressing || state == DeploymentState.AtEnd;
public static Interpolator Default()
{
return new Interpolator()
{
maxSpeed = 1
};
}
public void Progress()
{
velocity = maxSpeed;
state = ProgressionState.Progressing;
}
public void Regress()
{
velocity = -maxSpeed;
state = ProgressionState.Regressing;
}
public void Toggle()
{
if (state == ProgressionState.AtEnd || state == ProgressionState.Progressing)
Regress();
else
Progress();
}
public void SetTo(float value)
{
value = Mathf.Clamp01(value);
progress = value;
velocity = 0;
if (value == 1)
state = ProgressionState.AtEnd;
else if (value == 0)
state = ProgressionState.AtStart;
else
state = ProgressionState.Progressing;
}
public void Update(float dt)
{
if (maxSpeed == 0)
return;
progress += velocity * dt;
if (velocity < 0 && progress < 0)
{
progress = 0;
if (state == ProgressionState.Regressing)
{
velocity = 0;
state = ProgressionState.AtStart;
}
}
else if (velocity > 0 && progress > 1)
{
progress = 1;
if (state == ProgressionState.Progressing)
{
velocity = 0;
state = ProgressionState.AtEnd;
}
}
}
}
[System.Serializable]
public struct InertialInterpolator : IInterpolator
{
public float maxSpeed;
public float acceleration;
public float brakingAcceleration;
[HideInInspector] public float progress;
[HideInInspector] public float velocity;
[HideInInspector] public float accel;
private ProgressionState state;
[HideInInspector] public bool braking;
private float endTarget;
private float beginTarget;
public ProgressionState State => state;
public bool Stopped => velocity == 0;
public static InertialInterpolator Default()
{
return new InertialInterpolator()
{
maxSpeed = 1f,
acceleration = 1f,
endTarget = 1f
};
}
public void Toggle()
{
if (state == ProgressionState.AtEnd || state == ProgressionState.Progressing)
Regress();
else
Progress();
}
private void ProgressTo(float to)
{
endTarget = to;
accel = acceleration;
state = ProgressionState.Progressing;
braking = velocity < 0;
if (braking)
accel = brakingAcceleration > 0 ? brakingAcceleration : acceleration;
}
public void Progress()
{
ProgressTo(1);
}
private void RegressTo(float to)
{
beginTarget = to;
accel = -acceleration;
state = ProgressionState.Regressing;
braking = velocity > 0;
if (braking)
accel = brakingAcceleration > 0 ? -brakingAcceleration : -acceleration;
}
public void Regress()
{
RegressTo(0);
}
/// <summary>
/// Sets the target to start accelerating to. Note, the input should always be 0-1
/// </summary>
/// <param name="to"></param>
public void AccelerateTo(float to)
{
if (progress < to)
ProgressTo(to);
else
RegressTo(to);
}
/// <summary>
/// The interpolator will start decelerating with brakingAcceleration eventually slowly coming to a stop,
/// overriding any progression status.
/// </summary>
public void StartBraking()
{
if (braking)
return;
braking = true;
switch (velocity)
{
case > 0:
ProgressTo(Mathf.Min(progress + StoppingDistance(velocity, -brakingAcceleration), 1));
return;
case < 0:
RegressTo(Mathf.Max(progress - -StoppingDistance(velocity, brakingAcceleration), 0));
return;
}
}
static float StoppingDistance(float curVelo, float accel)
{
return curVelo * curVelo / (2 * -accel);
}
public void Update(float dt)
{
if (maxSpeed == 0)
Debug.Log("MaxSpeed of a Deployer is 0, there will be no movement. Please set it before using");
// Limit velocity
if (velocity < -maxSpeed)
{
accel = 0;
velocity = -maxSpeed + Mathf.Epsilon;
}
else if (velocity > maxSpeed)
{
accel = 0;
velocity = maxSpeed - Mathf.Epsilon;
}
if (brakingAcceleration > 0 && !braking)
{
// TODO: Handle the case where braking force is so big that it immediately reverses the direction
// In that case we should skip braking state entirely
if (velocity > 0 && state == ProgressionState.Progressing)
{
float stopDist = StoppingDistance(velocity, -brakingAcceleration);
if (progress > endTarget - stopDist)
{
accel = -brakingAcceleration;
braking = true;
}
}
else if (velocity < 0 && state == ProgressionState.Regressing)
{
float stopDist = -StoppingDistance(velocity, brakingAcceleration);
if (progress < beginTarget + stopDist)
{
accel = brakingAcceleration;
braking = true;
}
}
}
if (braking)
{
if (accel < 0 && velocity < 0)
{
if (state == ProgressionState.Progressing)
SetTo(endTarget);
else
{
braking = false;
accel = -acceleration;
}
}
else if (accel > 0 && velocity > 0)
{
if (state == ProgressionState.Regressing)
SetTo(beginTarget);
else
{
braking = false;
accel = acceleration;
}
}
}
velocity += accel * dt;
progress += velocity * dt;
// Clamp between 0-1
if (velocity < 0 && progress < 0)
{
progress = 0;
velocity = 0;
if (state == ProgressionState.Regressing)
SetTo(0);
}
else if (velocity > 0 && progress > 1)
{
progress = 1;
velocity = 0;
if (state == ProgressionState.Progressing)
SetTo(1);
}
}
public void SetTo(float value)
{
value = Mathf.Clamp01(value);
progress = value;
velocity = 0;
accel = 0;
braking = false;
if (value == 1)
state = ProgressionState.AtEnd;
else if (value == 0)
state = ProgressionState.AtStart;
else
state = ProgressionState.Progressing;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9eeaa9ab61b55044a81d9d7221b8a153
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: