場景佈置
運行效果:
層次面板
實現方法
- 使用LineRenderer作爲鉤鏈
- 在BeginPoint物體上添加LineRenderer組件,記得取消勾選 use world space
使用小球(Hook)作爲鉤子
當發射時對鉤子進行碰撞檢測
- 檢測到敵人便將敵人作爲鉤子的子物體
- 添加膠囊體Enemy,並將tag設置”Enemy”
代碼部分
附件於Hand上
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Hook: MonoBehaviour
{
public LineRenderer hookObj; //鉤子起始點 附加有LineRenderer組件
public float hookSpeed = 10f; //鉤子發射速度
public float totalDistance = 3f; //鉤子最大長度
public bool isOut = false; //鉤子發射或者收回標記
public Transform hookTransform; //鉤子物體(即小球)
private Collider[] colCollection; //發射中碰撞到的物體
private float oriZvalue;
private bool isStop = true; //用來判斷鉤子是否停止
private float tempZvalue;
// Use this for initialization
void Start() {
oriZvalue = hookTransform.localPosition.z;
tempZvalue = oriZvalue;
}
// Update is called once per frame
void Update() {
checkCollider(); //檢測發射過程中碰到的碰撞體
CheckLength(); //檢測是否超過鉤子長度
if (Input.GetKeyDown(KeyCode.H)) {
isOut = true;
}
//發射鉤子
if (isOut) {
hookTransform.Translate(0, 0, hookSpeed * Time.deltaTime);
hookObj.SetPosition(1, hookTransform.localPosition);
}
//收回鉤子
else {
if (hookTransform.localPosition.z > oriZvalue) {
hookTransform.Translate(0, 0, -hookSpeed * Time.deltaTime);
hookObj.SetPosition(1, hookTransform.localPosition);
}
}
//判斷鉤子是否爲停止狀態
if (hookTransform.childCount > 0) {
isStop = Mathf.Abs(hookTransform.localPosition.z - tempZvalue) <= 0 ? true : false;
}
else
isStop = false;
//將敵人夠到身前後,放開鉤子
if (isStop) RealeaseChild();
}
private void LateUpdate() {
tempZvalue = hookTransform.localPosition.z;
}
void CheckLength() {
if (Vector3.Distance(hookTransform.position, hookObj.transform.position) > totalDistance) {
isOut = false;
}
}
void checkCollider() {
//對鉤子進行球形檢測,返回所有碰到或者在球範圍內的碰撞體數組
//注意將人稱控制器及其子物體的Layer修改爲不是Default的一個層,否則鉤子會檢測到自身的碰撞體
colCollection = Physics.OverlapSphere(hookTransform.position, 0.2f, 1 << LayerMask.NameToLayer("Default"));
if (colCollection.Length > 0) {
foreach (Collider item in colCollection) {
//將敵人的tag設置爲“Enemy”
if (item.gameObject.tag.Equals("Enemy"))
item.transform.SetParent(hookTransform);
}
isOut = false;
}
}
void RealeaseChild() {
if (hookTransform.childCount > 0) {
for (int i = 0; i < hookTransform.childCount; i++) {
hookTransform.GetChild(i).transform.SetParent(null);
}
}
}
}
附加於Enemy上 進行pingpong運動
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemymove : MonoBehaviour {
public float moveSpeed = 3;
public float zVlaue=5;
private Vector3 ori;
private float timer = 0;
private Vector3 targetPoi = Vector3.zero;
private Quaternion oriRot;
// Use this for initialization
void Start () {
ori = transform.position;
oriRot = transform.rotation;
}
// Update is called once per frame
void Update () {
//當沒被鉤中時,進行pingpong運動
if (transform.parent == null) {
transform.rotation = oriRot; //更新爲初始旋轉,否則在放鉤後旋轉會改變
timer += Time.deltaTime*2;
zVlaue = Mathf.PingPong(timer, 7);
targetPoi = transform.right * zVlaue;
transform.position = ori + targetPoi;
}
//當背鉤中時
else {
ori = new Vector3(transform.position.x, 0.98f, transform.position.z);
timer = 0;
}
}
}
完