Skip to content

Instantly share code, notes, and snippets.

@planaria
Created August 18, 2023 07:58
Show Gist options
  • Save planaria/bc0ffeab5f99f57a8eb86d1e57f59927 to your computer and use it in GitHub Desktop.
Save planaria/bc0ffeab5f99f57a8eb86d1e57f59927 to your computer and use it in GitHub Desktop.
using UdonSharp;
using UnityEngine;
using UnityEngine.UI;
using VRC.SDKBase;
using VRC.Udon;
public class Moto : UdonSharpBehaviour
{
public Text debugText;
public GameObject bike;
public Transform bikeTransform;
public Rigidbody bikeRigidbody;
public Transform frontTransform;
public WheelCollider frontWheelCollider;
public Transform rearTransform;
public WheelCollider rearWheelCollider;
public UdonBehaviour leftGrip;
public UdonBehaviour rightGrip;
public BoxCollider standCollider;
public Transform axisTransform;
public AudioSource audioSource;
public UdonBehaviour station;
[UdonSynced(UdonSyncMode.Linear)]
private float frontAngle = 0.0f;
[UdonSynced(UdonSyncMode.Linear)]
private float rearAngle = 0.0f;
[UdonSynced(UdonSyncMode.Linear)]
private float smoothedSteerAngle = 0.0f;
[UdonSynced]
private bool running = false;
[UdonSynced(UdonSyncMode.Linear)]
private float accel = 0.0f;
[UdonSynced(UdonSyncMode.None)]
private float lastTime = 0.0f;
void Update()
{
// string s = "";
var isOwner = Networking.IsOwner(bike);
if (isOwner)
{
frontAngle += frontWheelCollider.rpm / 60.0f * Time.deltaTime;
frontAngle %= 100.0f;
rearAngle += rearWheelCollider.rpm / 60.0f * Time.deltaTime;
rearAngle %= 100.0f;
running = (bool)leftGrip.GetProgramVariable("pickup") || (bool)rightGrip.GetProgramVariable("pickup");
if (!Networking.LocalPlayer.IsUserInVR() && (bool)station.GetProgramVariable("seated"))
{
running = true;
}
var steerAngle = 0.0f;
if (running)
{
accel = Mathf.Clamp((float)rightGrip.GetProgramVariable("angle") * -1.0f, 0.0f, 90.0f) * 1.0f;
if (Input.GetKey(KeyCode.UpArrow))
{
accel = 45.0f;
}
if (accel < 1.0f)
{
accel = 0.0f;
}
rearWheelCollider.motorTorque = accel;
var frontBrake = (bool)rightGrip.GetProgramVariable("trigger") ? 100.0f : 0.0f;
var rearBrake = (bool)leftGrip.GetProgramVariable("trigger") ? 100.0f : 0.0f;
if (Input.GetKey(KeyCode.DownArrow))
{
frontBrake = 100.0f;
rearBrake = 100.0f;
}
frontWheelCollider.brakeTorque = frontBrake;
rearWheelCollider.brakeTorque = rearBrake;
var vForward = bikeRigidbody.rotation * new Vector3(0.0f, 0.0f, 1.0f);
var vUp = bikeRigidbody.rotation * new Vector3(0.0f, 1.0f, 0.0f);
var vel = Vector3.Dot(vForward, bikeRigidbody.velocity);
var leftPos = (float)leftGrip.GetProgramVariable("pos");
var rightPos = (float)rightGrip.GetProgramVariable("pos");
steerAngle = Mathf.Atan2(leftPos - rightPos, 0.3f) * Mathf.Rad2Deg;
if (Input.GetKey(KeyCode.LeftArrow))
{
steerAngle = -10.0f;
}
else if (Input.GetKey(KeyCode.RightArrow))
{
steerAngle = 10.0f;
}
steerAngle = Mathf.Clamp(steerAngle, -30, 30);
var vLeft = new Vector3(-vForward.z, 0.0f, vForward.x);
var vVirtualUp = Vector3.Cross(vForward, vLeft).normalized;
var angle = Mathf.Asin(Mathf.Clamp(Vector3.Dot(vForward, Vector3.Cross(vUp, vVirtualUp)), -1.0f, 1.0f));
var angularVelocity = Vector3.Dot(vForward, bikeRigidbody.angularVelocity);
var kp = 500.0f;
var kd = 0.0f;
var dp = Mathf.Clamp(-smoothedSteerAngle * Mathf.Deg2Rad - angle, -0.5f, 0.5f);
var torque = (dp * kp - angularVelocity * kd) * vel;
bikeRigidbody.AddRelativeTorque(new Vector3(0.0f, 0.0f, torque));
lastTime = Time.time;
}
else
{
accel = 0.0f;
rearWheelCollider.motorTorque = accel;
frontWheelCollider.brakeTorque = 0.0f;
rearWheelCollider.brakeTorque = 0.0f;
steerAngle = 0.0f;
if (lastTime != 0.0f && Time.time - lastTime > 600.0)
{
bikeTransform.position = new Vector3(0.0f, 0.0f, -1000.0f);
lastTime = Time.time;
}
}
smoothedSteerAngle = Mathf.Lerp(smoothedSteerAngle, steerAngle, 0.1f);
frontWheelCollider.steerAngle = smoothedSteerAngle;
bikeRigidbody.maxAngularVelocity = 7.0f;
bikeRigidbody.maxDepenetrationVelocity = 16.0f;
bikeRigidbody.velocity = Vector3.ClampMagnitude(bikeRigidbody.velocity, 16.0f);
}
frontTransform.localRotation = Quaternion.AngleAxis(frontAngle * 360.0f, new Vector3(1.0f, 0.0f, 0.0f));
rearTransform.localRotation = Quaternion.AngleAxis(rearAngle * 360.0f, new Vector3(1.0f, 0.0f, 0.0f));
var axisAngles = axisTransform.localEulerAngles;
axisAngles.z = smoothedSteerAngle;
axisTransform.localEulerAngles = axisAngles;
standCollider.enabled = !running;
audioSource.enabled = running;
audioSource.pitch = 1.0f + accel * 0.01f;
// debugText.text = s;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment