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);
 | 
						|
        }
 | 
						|
    }
 | 
						|
} |