*
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
|
||||
|
||||
[Serializable]
|
||||
public class GravityRayConfig{
|
||||
public float radius = 0.5f;
|
||||
public float length = 5.0f;
|
||||
public float tileLength = 3.0f;
|
||||
|
||||
public static bool operator==(GravityRayConfig c1, GravityRayConfig c2){
|
||||
return c1.radius == c2.radius && c1.length == c2.length && c1.tileLength == c2.tileLength;
|
||||
}
|
||||
public static bool operator!=(GravityRayConfig c1, GravityRayConfig c2){
|
||||
return c1.radius != c2.radius || c1.length != c2.length || c1.tileLength != c2.tileLength;
|
||||
}
|
||||
public void AssignFrom(GravityRayConfig other){
|
||||
radius = other.radius;
|
||||
length = other.length;
|
||||
tileLength = other.tileLength;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[ExecuteInEditMode]
|
||||
public class GravityRayBody : MonoBehaviour {
|
||||
public GravityRayConfig config;
|
||||
private GravityRayConfig lastConfig = new GravityRayConfig();
|
||||
private const string rayObjectName = "Beam";
|
||||
public Material beamMaterial;
|
||||
GameObject ray = null;
|
||||
List<GameObject> capturedObjects = new List<GameObject>();
|
||||
public float centeringForce = 0.5f;
|
||||
public float dragForce = 0.5f;
|
||||
|
||||
// Use this for initialization
|
||||
void Start () {
|
||||
RebuildRay ();
|
||||
lastConfig = config;
|
||||
}
|
||||
|
||||
void RebuildRay(){
|
||||
lastConfig.AssignFrom (config);
|
||||
|
||||
if (ray == null) {
|
||||
ray = AdvancedUtils.FindChild(gameObject, rayObjectName);
|
||||
}
|
||||
if (ray == null) {
|
||||
ray = AdvancedUtils.CreateMeshObject(rayObjectName);
|
||||
ray.transform.parent = transform;
|
||||
ray.transform.localPosition = Vector3.zero;
|
||||
ray.transform.localRotation = Quaternion.identity;
|
||||
ray.transform.localScale = Vector3.one;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CapsuleCollider c = gameObject.GetComponent<CapsuleCollider> ();
|
||||
if (c == null) {
|
||||
c = gameObject.AddComponent<CapsuleCollider>();
|
||||
}
|
||||
|
||||
c.center = new Vector3 (0, config.length * 0.5f, 0);
|
||||
c.radius = config.radius;
|
||||
c.height = config.length;
|
||||
c.direction = 1;
|
||||
c.isTrigger = true;
|
||||
|
||||
var mf = ray.GetComponent<MeshFilter> ();
|
||||
var m = mf.sharedMesh;
|
||||
|
||||
|
||||
Vector3[] vertices;
|
||||
Vector3[] normals;
|
||||
int[] indices;
|
||||
Vector2[] uvs;
|
||||
AdvancedUtils.GenerateCylinder (config.radius, config.length, 33, 1,2, config.length / config.tileLength, out vertices, out indices, out uvs, out normals);
|
||||
|
||||
m.vertices = vertices;
|
||||
m.SetIndices (indices, MeshTopology.Triangles, 0);
|
||||
m.normals = normals;
|
||||
m.uv = uvs;
|
||||
m.RecalculateBounds ();
|
||||
ray.renderer.sharedMaterial = beamMaterial;
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void FixedUpdate () {
|
||||
if (ray != null) {
|
||||
ray.transform.Rotate (Vector3.up, Time.deltaTime * -90.0f);
|
||||
}
|
||||
|
||||
if(lastConfig != config){
|
||||
RebuildRay();
|
||||
}
|
||||
|
||||
foreach (var obj in capturedObjects) {
|
||||
Vector3 a;
|
||||
Vector3 b;
|
||||
|
||||
GetCylinderPoints(out a, out b);
|
||||
|
||||
|
||||
Vector3 n = (b - a).normalized;
|
||||
Vector3 p = AdvancedMath.LineNearestPoint(a, b, obj.transform.position);
|
||||
Vector3 centeringDir = (p - obj.transform.position).normalized;
|
||||
|
||||
|
||||
//Debug.Log(centeringDir);
|
||||
obj.rigidbody.velocity += centeringDir * centeringForce * Time.deltaTime;
|
||||
|
||||
float forwardSpeed = Vector3.Dot(n, obj.rigidbody.velocity);
|
||||
float diff = dragForce - forwardSpeed;
|
||||
obj.rigidbody.velocity += n * dragForce * Time.deltaTime * 0.9f * diff;
|
||||
|
||||
//obj.rigidbody.velocity =obj.rigidbody.velocity * 0.9f * Time.deltaTime + centeringDir * centeringForce * Time.deltaTime + n * dragForce * Time.deltaTime;
|
||||
}
|
||||
}
|
||||
|
||||
void GetCylinderPoints(out Vector3 a, out Vector3 b){
|
||||
a = ray.transform.position;
|
||||
b = ray.transform.position + ray.transform.up * config.length;
|
||||
}
|
||||
|
||||
void OnTriggerEnter(Collider other){
|
||||
if (other.rigidbody!= null && !other.rigidbody.isKinematic && !capturedObjects.Contains (other.gameObject)) {
|
||||
capturedObjects.Add(other.gameObject);
|
||||
other.rigidbody.useGravity = false;
|
||||
other.rigidbody.velocity = Vector3.zero;
|
||||
Debug.Log("Beam captured object: " + other.name);
|
||||
}
|
||||
}
|
||||
|
||||
void OnTriggerExit(Collider other){
|
||||
if (capturedObjects.Contains (other.gameObject)) {
|
||||
capturedObjects.Remove(other.gameObject);
|
||||
other.rigidbody.useGravity = true;
|
||||
Debug.Log("Beam lost object: " + other.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OnDrawGizmos(){
|
||||
if(lastConfig != config){
|
||||
RebuildRay();
|
||||
}
|
||||
|
||||
if(ray != null){
|
||||
Vector3 a;
|
||||
Vector3 b;
|
||||
|
||||
GetCylinderPoints(out a, out b);
|
||||
Gizmos.DrawWireSphere(a, 0.2f);
|
||||
Gizmos.DrawWireSphere(b, 0.2f);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user