04-08-2020, 01:11 AM
(03-08-2020, 08:31 AM)josemendez Wrote: Can you post your whole script?
Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Obi;
public class GrapplingHook : MonoBehaviour
{
public ObiSolver solver;
public ObiCollider character;
public float hookExtendRetractSpeed = 2;
public ObiRopeSection section;
public GameObject chain;
private List<GameObject> PrefabsList;
public ObiRope rope;
private ObiRopeBlueprint blueprint;
private ObiRopeExtrudedRenderer ropeRenderer;
private ObiRopeChainRenderer chainRenderer;
private ObiRopeCursor cursor;
//private Camera cam;
public RaycastHit hookAttachment;
KeyCode interKey = KeyCode.Joystick1Button0;
KeyCode addRope = KeyCode.Joystick1Button4;
KeyCode lessRope = KeyCode.Joystick1Button5;
public SpeedTutorInspectSystem.InspectionRaycast playerIns;
private bool attached = false;
private GameObject maincam;
private bool doOnce;
private SpeedTutorInspectSystem.ObjectController raycastedObj;
[SerializeField] private int rayLength = 15;
public RaycastHit hit;
void Awake()
{
//找到玩家身上的主攝像機
GameObject camobject = GameObject.FindGameObjectWithTag("MainCamera");
maincam = camobject;
//這裡學到一個超牛的,之前我沒有給chain初始化,public GameObject chain並沒有定義,下面必須初始化,否則後面的一切,update都不會觸發!
//chain = new GameObject();
PrefabsList = new List<GameObject>();
PrefabsList.Add((GameObject)Instantiate(chain, Vector3.zero, Quaternion.identity));
PrefabsList.Add((GameObject)Instantiate(chain, Vector3.zero, Quaternion.identity));
// Create both the rope and the solver:
rope = gameObject.AddComponent<ObiRope>();
chainRenderer = gameObject.AddComponent<ObiRopeChainRenderer>();
chainRenderer.linkPrefabs = PrefabsList;
chainRenderer.linkScale = new Vector3(34,34,34);
chainRenderer.twistAnchor = 0;
chainRenderer.sectionTwist = 70;
// 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;
}
private void OnDestroy()
{
DestroyImmediate(blueprint);
}
public void LaunchHook()
{
//這裡一定是要從攝影機發射出來的ray才行,弄了半天才找到答案!
//下面還有debugray的一種方法就是畫debug的線
Ray ray = new Ray(transform.position, maincam.transform.forward);
if (Physics.Raycast(ray, out hookAttachment))
{
//Debug.DrawLine(ray.origin, hookAttachment.point, Color.red);
StartCoroutine(AttachHook());
}
else
{
Debug.DrawLine(ray.origin, ray.origin + ray.direction*100, Color.green);
}
}
private IEnumerator AttachHook()
{
yield return 0;
Vector3 localHit = rope.transform.InverseTransformPoint(hookAttachment.point);
// 將rope由兩點畫出來:
blueprint.path.Clear();
blueprint.path.AddControlPoint(Vector3.zero, -localHit.normalized, localHit.normalized, Vector3.up, 0.1f, 0.1f, 1, 1, Color.white, "Hook start");
blueprint.path.AddControlPoint(localHit, -localHit.normalized, localHit.normalized, Vector3.up, 0.1f, 0.1f, 1, 1, Color.white, "Hook end");
blueprint.path.FlushEvents();
// 畫出rope的blueprint:
yield return blueprint.Generate();
// 設置兩點的交互,rope對物體的影響在這裡設置:
var pinConstraints = blueprint.GetConstraintsByType(Oni.ConstraintType.Pin) as ObiConstraints<ObiPinConstraintsBatch>;
var batch = pinConstraints.batches[0];
batch.AddConstraint(0, character, transform.localPosition, Quaternion.identity);
batch.AddConstraint(blueprint.activeParticleCount - 1, hookAttachment.collider.GetComponent<ObiColliderBase>(),
hookAttachment.collider.transform.InverseTransformPoint(hookAttachment.point), Quaternion.identity);
batch.stiffnesses[0 * 2 + 1] = 100000000;
batch.stiffnesses[1 * 2 + 1] = 100000000;
batch.activeConstraintCount = 2;
//batch.stiffnesses[constraintIndex * 2 + 1] = 10000;
// 最終顯示出來.
rope.ropeBlueprint = blueprint;
rope.GetComponent<ObiRopeChainRenderer>().enabled = true;
}
public void DetachHook()
{
// Set the rope blueprint to null (automatically removes the previous blueprint from the solver, if any).
rope.ropeBlueprint = null;
rope.GetComponent<ObiRopeChainRenderer>().enabled = false;
}
void Update()
{
//如果用getkey的話就會一秒內按無數次,必須是Getkeydown才可以!gfg
if (Input.GetKeyDown(interKey))
{
if (!rope.isLoaded)
{
LaunchHook();
}
else
DetachHook();
}
if (rope.isLoaded)
{
if (Input.GetKey(lessRope))
{
cursor.ChangeLength(rope.restLength - hookExtendRetractSpeed * Time.deltaTime);
}
if (Input.GetKey(addRope))
{
cursor.ChangeLength(rope.restLength + hookExtendRetractSpeed * Time.deltaTime);
}
}
}
}