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.
81 lines
3.4 KiB
C#
81 lines
3.4 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
|
|
namespace Autohand {
|
|
public enum MagnetEffect {
|
|
Attractive,
|
|
Repulsive
|
|
}
|
|
|
|
[Serializable]
|
|
public class UnityMagneticEvent : UnityEvent<MagneticSource, MagneticBody> { }
|
|
|
|
[Serializable]
|
|
[HelpURL("https://app.gitbook.com/s/5zKO0EvOjzUDeT2aiFk3/auto-hand/extras/magnetic-forces")]
|
|
public class MagneticSource : MonoBehaviour {
|
|
public Rigidbody body;
|
|
public MagnetEffect magneticEffect;
|
|
public float strength = 10f;
|
|
public float radius = 4f;
|
|
public ForceMode forceMode = ForceMode.Force;
|
|
public AnimationCurve forceDistanceCurce = AnimationCurve.Linear(0, 0, 1, 1);
|
|
public int magneticIndex = 0;
|
|
public UnityMagneticEvent magneticEnter;
|
|
public UnityMagneticEvent magneticExit;
|
|
|
|
List<MagneticBody> magneticBodies = new List<MagneticBody>();
|
|
float radiusScale;
|
|
private void Start() {
|
|
if(body == null)
|
|
body = GetComponent<Rigidbody>();
|
|
radiusScale = transform.lossyScale.x < transform.lossyScale.y ? transform.lossyScale.x : transform.lossyScale.y;
|
|
radiusScale = radiusScale < transform.lossyScale.z ? radiusScale : transform.lossyScale.z;
|
|
}
|
|
|
|
private void FixedUpdate() {
|
|
foreach(var magneticBody in magneticBodies) {
|
|
var position = transform.position;
|
|
var otherPosition = magneticBody.transform.position;
|
|
var distance = Vector3.Distance(position, otherPosition);
|
|
if(distance < radius * radiusScale) {
|
|
var distanceValue = distance / (radius * radiusScale + 0.0001f);
|
|
var distanceMulti = forceDistanceCurce.Evaluate(distanceValue) * magneticBody.strengthMultiplyer * strength;
|
|
distanceMulti *= magneticEffect == MagnetEffect.Repulsive ? -1 : 1;
|
|
magneticBody.body.AddForce((position - otherPosition).normalized * distanceMulti, forceMode);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnTriggerEnter(Collider other) {
|
|
if(other.attachedRigidbody != null && other.CanGetComponent<MagneticBody>(out var magnetBody)) {
|
|
if(!magneticBodies.Contains(magnetBody) && magnetBody.magneticIndex == magneticIndex) {
|
|
magneticBodies.Add(magnetBody);
|
|
magneticEnter?.Invoke(this, magnetBody);
|
|
magnetBody.magneticEnter?.Invoke(this, magnetBody);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
private void OnTriggerExit(Collider other) {
|
|
if(other.attachedRigidbody != null && other.CanGetComponent<MagneticBody>(out var magnetBody)) {
|
|
if(magneticBodies.Contains(magnetBody)) {
|
|
magneticBodies.Remove(magnetBody);
|
|
magneticExit?.Invoke(this, magnetBody);
|
|
magnetBody.magneticExit?.Invoke(this, magnetBody);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private void OnDrawGizmosSelected() {
|
|
Gizmos.color = Color.blue;
|
|
var radiusScale = transform.lossyScale.x < transform.lossyScale.y ? transform.lossyScale.x : transform.lossyScale.y;
|
|
radiusScale = radiusScale < transform.lossyScale.z ? radiusScale : transform.lossyScale.z;
|
|
Gizmos.DrawWireSphere(transform.position, radius * radiusScale);
|
|
}
|
|
}
|
|
} |