修改水
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Obi;
|
||||
|
||||
/**
|
||||
* Sample component that shows how to use Obi Rope to create a grappling hook for a 2.5D game.
|
||||
@@ -14,142 +15,138 @@ using UnityEngine;
|
||||
* If complex interaction is required with the scene, a purely geometry-based approach (ala Worms ninja rope) can
|
||||
* be the right choice under certain circumstances.
|
||||
*/
|
||||
|
||||
namespace Obi.Samples
|
||||
public class GrapplingHook : MonoBehaviour
|
||||
{
|
||||
public class GrapplingHook : MonoBehaviour
|
||||
|
||||
public ObiSolver solver;
|
||||
public ObiCollider character;
|
||||
public float hookExtendRetractSpeed = 2;
|
||||
public Material material;
|
||||
public ObiRopeSection section;
|
||||
|
||||
private ObiRope rope;
|
||||
private ObiRopeBlueprint blueprint;
|
||||
private ObiRopeExtrudedRenderer ropeRenderer;
|
||||
|
||||
private ObiRopeCursor cursor;
|
||||
|
||||
private RaycastHit hookAttachment;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
|
||||
public ObiSolver solver;
|
||||
public ObiCollider character;
|
||||
public float hookExtendRetractSpeed = 2;
|
||||
public Material material;
|
||||
public ObiRopeSection section;
|
||||
// Create both the rope and the solver:
|
||||
rope = gameObject.AddComponent<ObiRope>();
|
||||
ropeRenderer = gameObject.AddComponent<ObiRopeExtrudedRenderer>();
|
||||
ropeRenderer.section = section;
|
||||
ropeRenderer.uvScale = new Vector2(1, 4);
|
||||
ropeRenderer.normalizeV = false;
|
||||
ropeRenderer.uvAnchor = 1;
|
||||
rope.GetComponent<MeshRenderer>().material = material;
|
||||
|
||||
private ObiRope rope;
|
||||
private ObiRopeBlueprint blueprint;
|
||||
private ObiRopeExtrudedRenderer ropeRenderer;
|
||||
// Setup a blueprint for the rope:
|
||||
blueprint = ScriptableObject.CreateInstance<ObiRopeBlueprint>();
|
||||
blueprint.resolution = 0.5f;
|
||||
|
||||
private ObiRopeCursor cursor;
|
||||
// Tweak rope parameters:
|
||||
rope.maxBending = 0.02f;
|
||||
|
||||
private RaycastHit hookAttachment;
|
||||
// Add a cursor to be able to change rope length:
|
||||
cursor = rope.gameObject.AddComponent<ObiRopeCursor>();
|
||||
cursor.cursorMu = 0;
|
||||
cursor.direction = true;
|
||||
}
|
||||
|
||||
void Awake()
|
||||
private void OnDestroy()
|
||||
{
|
||||
DestroyImmediate(blueprint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Raycast against the scene to see if we can attach the hook to something.
|
||||
*/
|
||||
private void LaunchHook()
|
||||
{
|
||||
|
||||
// Get the mouse position in the scene, in the same XY plane as this object:
|
||||
Vector3 mouse = Input.mousePosition;
|
||||
mouse.z = transform.position.z - Camera.main.transform.position.z;
|
||||
Vector3 mouseInScene = Camera.main.ScreenToWorldPoint(mouse);
|
||||
|
||||
// Get a ray from the character to the mouse:
|
||||
Ray ray = new Ray(transform.position, mouseInScene - transform.position);
|
||||
|
||||
// Raycast to see what we hit:
|
||||
if (Physics.Raycast(ray, out hookAttachment))
|
||||
{
|
||||
|
||||
// Create both the rope and the solver:
|
||||
rope = gameObject.AddComponent<ObiRope>();
|
||||
ropeRenderer = gameObject.AddComponent<ObiRopeExtrudedRenderer>();
|
||||
ropeRenderer.section = section;
|
||||
ropeRenderer.uvScale = new Vector2(1, 4);
|
||||
ropeRenderer.normalizeV = false;
|
||||
ropeRenderer.uvAnchor = 1;
|
||||
rope.GetComponent<MeshRenderer>().material = material;
|
||||
|
||||
// Setup a blueprint for the rope:
|
||||
blueprint = ScriptableObject.CreateInstance<ObiRopeBlueprint>();
|
||||
blueprint.resolution = 0.5f;
|
||||
|
||||
// Tweak rope parameters:
|
||||
rope.maxBending = 0.02f;
|
||||
|
||||
// Add a cursor to be able to change rope length:
|
||||
cursor = rope.gameObject.AddComponent<ObiRopeCursor>();
|
||||
cursor.cursorMu = 0;
|
||||
cursor.direction = true;
|
||||
// We actually hit something, so attach the hook!
|
||||
StartCoroutine(AttachHook());
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
}
|
||||
|
||||
private IEnumerator AttachHook()
|
||||
{
|
||||
yield return 0;
|
||||
Vector3 localHit = rope.transform.InverseTransformPoint(hookAttachment.point);
|
||||
|
||||
int filter = ObiUtils.MakeFilter(ObiUtils.CollideWithEverything,0);
|
||||
|
||||
// Procedurally generate the rope path (a simple straight line):
|
||||
blueprint.path.Clear();
|
||||
blueprint.path.AddControlPoint(Vector3.zero, -localHit.normalized, localHit.normalized, Vector3.up, 0.1f, 0.1f, 1, filter, Color.white, "Hook start");
|
||||
blueprint.path.AddControlPoint(localHit, -localHit.normalized, localHit.normalized, Vector3.up, 0.1f, 0.1f, 1, filter, Color.white, "Hook end");
|
||||
blueprint.path.FlushEvents();
|
||||
|
||||
// Generate the particle representation of the rope (wait until it has finished):
|
||||
yield return blueprint.Generate();
|
||||
|
||||
// Set the blueprint (this adds particles/constraints to the solver and starts simulating them).
|
||||
rope.ropeBlueprint = blueprint;
|
||||
rope.GetComponent<MeshRenderer>().enabled = true;
|
||||
|
||||
// Pin both ends of the rope (this enables two-way interaction between character and rope):
|
||||
var pinConstraints = rope.GetConstraintsByType(Oni.ConstraintType.Pin) as ObiConstraints<ObiPinConstraintsBatch>;
|
||||
pinConstraints.Clear();
|
||||
var batch = new ObiPinConstraintsBatch();
|
||||
batch.AddConstraint(rope.solverIndices[0], character, transform.localPosition, Quaternion.identity, 0, 0, float.PositiveInfinity);
|
||||
batch.AddConstraint(rope.solverIndices[blueprint.activeParticleCount - 1], hookAttachment.collider.GetComponent<ObiColliderBase>(),
|
||||
hookAttachment.collider.transform.InverseTransformPoint(hookAttachment.point), Quaternion.identity, 0, 0, float.PositiveInfinity);
|
||||
batch.activeConstraintCount = 2;
|
||||
pinConstraints.AddBatch(batch);
|
||||
|
||||
rope.SetConstraintsDirty(Oni.ConstraintType.Pin);
|
||||
}
|
||||
|
||||
private void DetachHook()
|
||||
{
|
||||
// Set the rope blueprint to null (automatically removes the previous blueprint from the solver, if any).
|
||||
rope.ropeBlueprint = null;
|
||||
rope.GetComponent<MeshRenderer>().enabled = false;
|
||||
}
|
||||
|
||||
|
||||
void Update()
|
||||
{
|
||||
|
||||
if (Input.GetMouseButtonDown(0))
|
||||
{
|
||||
DestroyImmediate(blueprint);
|
||||
if (!rope.isLoaded)
|
||||
LaunchHook();
|
||||
else
|
||||
DetachHook();
|
||||
}
|
||||
|
||||
/**
|
||||
* Raycast against the scene to see if we can attach the hook to something.
|
||||
*/
|
||||
private void LaunchHook()
|
||||
if (rope.isLoaded)
|
||||
{
|
||||
|
||||
// Get the mouse position in the scene, in the same XY plane as this object:
|
||||
Vector3 mouse = Input.mousePosition;
|
||||
mouse.z = transform.position.z - Camera.main.transform.position.z;
|
||||
Vector3 mouseInScene = Camera.main.ScreenToWorldPoint(mouse);
|
||||
|
||||
// Get a ray from the character to the mouse:
|
||||
Ray ray = new Ray(transform.position, mouseInScene - transform.position);
|
||||
|
||||
// Raycast to see what we hit:
|
||||
if (Physics.Raycast(ray, out hookAttachment))
|
||||
if (Input.GetKey(KeyCode.W))
|
||||
{
|
||||
// We actually hit something, so attach the hook!
|
||||
StartCoroutine(AttachHook());
|
||||
cursor.ChangeLength(rope.restLength - hookExtendRetractSpeed * Time.deltaTime);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private IEnumerator AttachHook()
|
||||
{
|
||||
yield return 0;
|
||||
Vector3 localHit = rope.transform.InverseTransformPoint(hookAttachment.point);
|
||||
|
||||
int filter = ObiUtils.MakeFilter(ObiUtils.CollideWithEverything, 0);
|
||||
|
||||
// Procedurally generate the rope path (a simple straight line):
|
||||
blueprint.path.Clear();
|
||||
blueprint.path.AddControlPoint(Vector3.zero, -localHit.normalized, localHit.normalized, Vector3.up, 0.1f, 0.1f, 1, filter, Color.white, "Hook start");
|
||||
blueprint.path.AddControlPoint(localHit, -localHit.normalized, localHit.normalized, Vector3.up, 0.1f, 0.1f, 1, filter, Color.white, "Hook end");
|
||||
blueprint.path.FlushEvents();
|
||||
|
||||
// Generate the particle representation of the rope (wait until it has finished):
|
||||
yield return blueprint.Generate();
|
||||
|
||||
// Set the blueprint (this adds particles/constraints to the solver and starts simulating them).
|
||||
rope.ropeBlueprint = blueprint;
|
||||
rope.GetComponent<MeshRenderer>().enabled = true;
|
||||
|
||||
// Pin both ends of the rope (this enables two-way interaction between character and rope):
|
||||
var pinConstraints = rope.GetConstraintsByType(Oni.ConstraintType.Pin) as ObiConstraints<ObiPinConstraintsBatch>;
|
||||
pinConstraints.Clear();
|
||||
var batch = new ObiPinConstraintsBatch();
|
||||
batch.AddConstraint(rope.solverIndices[0], character, transform.localPosition, Quaternion.identity, 0, 0);
|
||||
batch.AddConstraint(rope.solverIndices[blueprint.activeParticleCount - 1], hookAttachment.collider.GetComponent<ObiColliderBase>(),
|
||||
hookAttachment.collider.transform.InverseTransformPoint(hookAttachment.point), Quaternion.identity, 0, 0);
|
||||
batch.activeConstraintCount = 2;
|
||||
pinConstraints.AddBatch(batch);
|
||||
|
||||
rope.SetConstraintsDirty(Oni.ConstraintType.Pin);
|
||||
}
|
||||
|
||||
private void DetachHook()
|
||||
{
|
||||
// Set the rope blueprint to null (automatically removes the previous blueprint from the solver, if any).
|
||||
rope.ropeBlueprint = null;
|
||||
rope.GetComponent<MeshRenderer>().enabled = false;
|
||||
}
|
||||
|
||||
|
||||
void Update()
|
||||
{
|
||||
|
||||
if (Input.GetMouseButtonDown(0))
|
||||
if (Input.GetKey(KeyCode.S))
|
||||
{
|
||||
if (!rope.isLoaded)
|
||||
LaunchHook();
|
||||
else
|
||||
DetachHook();
|
||||
}
|
||||
|
||||
if (rope.isLoaded)
|
||||
{
|
||||
if (Input.GetKey(KeyCode.W))
|
||||
{
|
||||
cursor.ChangeLength(rope.restLength - hookExtendRetractSpeed * Time.deltaTime);
|
||||
}
|
||||
if (Input.GetKey(KeyCode.S))
|
||||
{
|
||||
cursor.ChangeLength(rope.restLength + hookExtendRetractSpeed * Time.deltaTime);
|
||||
}
|
||||
cursor.ChangeLength(rope.restLength + hookExtendRetractSpeed * Time.deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user