2 回答
TA贡献1877条经验 获得超1个赞
基本上,Find(name)
只返回该名称的任何内容的第一个实例,因此您g = Find(name)
几乎可以保证永远不会成为与您的触发/碰撞条件相关的对象。OnTriggerStay(Collider other)
已经为您提供了触发区域中的“其他”对撞机,因此请使用它。:)
替换这个:
GameObject g = GameObject.Find("Detection"); Fighting fScript = g.GetComponent<Fighting>();
有了这个:
Fighting fScript = other.GetComponent<Fighting>();
TA贡献1856条经验 获得超11个赞
对于您的问题标题:
每个 instaced(非静态)值对于相应的组件都是唯一的,因此对于GameObject它所附加的相应组件来说也是唯一的。您可能想重新提出这个问题,因为这实际上不是您的问题。
问题是当你这样做时
GameObject.Find("Detection");
它实际上两次都找到了相同的对象:即层次结构中的第一个对象。因此,在两个组件之一中,您可以找到自己的空对象并跳过其余部分
if(self.Team != FScript.Team)
..你可以尝试使用
other.Find("Detection");
而是仅在相应的上下文中搜索..但是,您根本不应该使用Find!
这是非常激烈的表现
您应该始终重复使用参考,而不是一遍又一遍地搜索它们
在你的情况下你不需要它
由于您说两个脚本都附加到同一个对象,您可以简单地使用
GetComponent<Fighting>();
你可以这样做Awake并重用参考:
private Fighting myFighting;
private void Awake()
{
myFighting = GetComponent<Fighting>();
}
与碰撞相比,您不必使用Find任何一种,因为您已经拥有与碰撞的对象的引用:other.gameObject。我不知道您的整个设置,但您可以在层次结构中向下搜索组件
// the flag true is sued to also find inactive gameObjects and components
// leave it without parameters if you don't want this
var otherFighting = other.GetComponentInChildren<Fighting>(true);
或在层次结构中向上搜索
var otherFighting = other.GetComponentInParent<Fighting>(true);
或者如果你已经知道你与正确的游戏对象完全碰撞,只需使用
var otherFighting = other.GetComponent<Fighting>();
我将在我的示例中使用后者。
比一直检查健康Update是一个巨大的性能问题。您应该有一个方法,例如TakeDamage,只有在您的健康状况实际发生变化时才进行检查:
斗争
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Fighting : MonoBehaviour
{
public int Team = 1;
public int Health = 100;
public int AttackDamage = 10;
public float CoolDown = 2;
public float original = 2;
// you don't need that flag see below
//public bool CoolingDown = false;
public bool Snap = false;
private void Update()
{
// you might also put this in a callback instead of update at some point later
if(Snap == true)
{
Destroy(transform.parent.gameObject);
}
// Note: this also makes not muh sense because if you destroyed
// the parent than you cannot instantiate it again!
// use a prefab instead
if (Input.GetKey(KeyCode.N)) Instantiate(transform.parent.gameObject);
}
public void TakeDamge(int DamageAmount)
{
Health -= DamageAmount;
if (Health > 0) return;
Destroy(transform.parent.gameObject);
}
}
一般的另一个性能问题:即使Start, Updateetc 是空的,如果它们存在于您的脚本中,Unity 也会调用它们。因此,如果您不使用它们,请完全删除它们以避免无用的开销。
所以我会
触发检测
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TrigDetect : MonoBehaviour
{
bool once = false;
private Fighting myFighting;
private void Awake()
{
myFighting = GetComponent<Fighting>();
}
void OnTriggerStay(Collider other)
{
// if wrong tag do nothing
if (!other.CompareTag("Troop")) return;
Fighting fScript = other.GetComponent<Fighting>();
// here you should add a check
if(!fScript)
{
// By using the other.gameObject as context you can find with which object
// you collided exactly by clicking on the Log
Debug.LogError("Something went wrong: Could not get the Fighting component of other", other.gameObject);
}
if (!once)
{
Debug.Log("I am the team:" + self.Team);
Debug.Log("I have detected the team:" + fScript.Team);
once = true;
}
// if same team do nothing
if (self.Team == fScript.Team) return;
// you don't need the CoolingDown bool at all:
self.CoolDown -= Time.deltaTime;
// if still cooling down do nothing
if(self.CoolDown > 0) return;
fScript.TakeDamage(self.AttackDamage);
self.CoolDown = self.original;
}
}
- 2 回答
- 0 关注
- 99 浏览
添加回答
举报