【发布时间】:2014-12-20 03:19:25
【问题描述】:
好吧,看来我正在重新解决这个问题。我正在经历的是,我想你可以说当我“消失”一个怪物(玩家已经杀死它)并“重生”它时,它会将所有动作重新添加到列表中。例如:
怪物 A 在他的列表中有 2 个动作:Scratch & Growl... 怪物 A 死了...... 怪物 A 重生... 怪物 A 现在在他的列表中有 4 个动作:Scratch & Growl...AND...抓挠和咆哮...
这是我的代码:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class MonsterMoves : MonoBehaviour {
public List<BaseMove> moves;
public int level;
public Scratch scratch = new Scratch();
public Growl growl = new Growl();
public FireBall fireball = new FireBall();
public PowerUp powerup = new PowerUp();
void Start(){
moves = gameObject.GetComponent<Monster>().monstersMoves;
level = gameObject.GetComponent<Monster>().level;
}
void Update(){
level = gameObject.GetComponent<Monster>().level;
SetupMoves(level);
}
private void SetupMoves(int level){
if(level >= 1 && !moves.Contains(scratch)){
moves.Add(scratch);
}
if(level >= 1 && !moves.Contains(growl)){
moves.Add(growl);
}
if(level >= 7 && !moves.Contains(fireball)){
moves.Add(fireball);
}
if(level >= 10 && !moves.Contains(powerup)){
moves.Add(powerup);
}
对我忽略的内容有什么想法吗?
回答一些cmets:
当怪物死去时,它的脚本(简称 Monster)会这样调用:
public void SetDead(){
isAlive = false;
timeOfDeath = Time.time;
ReSpawner.deadMonster.Add(this);
this.gameObject.SetActive(false);
}
这会处理“消失”怪物,而不是实际摧毁它。然后是处理重生的这个脚本:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class ReSpawner : MonoBehaviour {
public float spawnDistance = 50.0f;
public float minSpawnDensity = 6f;
public float minSpawnDistance = 20f;
public int respawnDelay = 10;
public static List<Monster> deadMonster = new List<Monster>();
private Vector3 spawnPoint;
private Vector3 lastSpawnPoint = Vector3.zero;
void Update(){
for(var i = 0; i < deadMonster.Count; i++){
Monster monster = deadMonster [i];
float time = Time.time - monster.timeOfDeath;
if(time > respawnDelay)
{
monster.gameObject.SetActive(true);
monster.isAlive = true;
monster.gameObject.rigidbody.WakeUp();
monster.gameObject.GetComponent<Animator>().enabled = true;
monster.gameObject.GetComponentInChildren<MonsterAI>().enabled = true;
spawnPoint = new Vector3(Random.Range(0, 2000), Random.Range(0, 2000), Random.Range(0, 2000));
spawnPoint.y = TerrainHeight(spawnPoint);
if(!IsInvalidSpawnPoint(spawnPoint, lastSpawnPoint)){
NavMeshHit closestHit;
if(NavMesh.SamplePosition(spawnPoint, out closestHit, 500, 1)){
spawnPoint = closestHit.position;
}else{
Debug.Log("...");
}
monster.gameObject.transform.position = spawnPoint;
monster.SetupMonster();
deadMonster.RemoveAt(i);
i--;
}
}
}
}
private bool IsInvalidSpawnPoint(Vector3 spawnPoint,Vector3 lastSpawnPoint){
if(spawnPoint.y == Mathf.Infinity || (spawnPoint - lastSpawnPoint).magnitude <= minSpawnDensity){
return true;
}else{
return false;
}
}
private float TerrainHeight(Vector3 spawnPoint){
Ray rayUp = new Ray(spawnPoint, Vector3.up);
Ray rayDown = new Ray(spawnPoint, Vector3.down);
RaycastHit hitPoint;
if(Physics.Raycast(rayUp, out hitPoint, Mathf.Infinity)){
return hitPoint.point.y;
}
else if(Physics.Raycast(rayDown, out hitPoint, Mathf.Infinity)){
return hitPoint.point.y;
}else{
return Mathf.Infinity;
}
}
}
我不愿发布整个“怪物”脚本,因为它相当广泛。
所以我做了一些改变。现在,每当第一次创建怪物时,我都会调用该函数,以及是否/何时升级。这是 MonsterMoves 的新脚本...
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[System.Serializable]
public class Moves : MonoBehaviour {
public List<Move> moves;
public List<Move> movesToLearn = new List<Move>();
void Start(){
moves = gameObject.GetComponent<Monster>().monstersMoves;
}
public void AddMoves(int level, List<Move> moves){
foreach(Move move in movesToLearn){
if(level >= move.levelLearned){
if(!moves.Contains(move)){
moves.Add(move);
}
}
}
}
}
我在处理怪物所有属性的脚本中调用这个函数。如果 Move 列表中已经包含该 move,我不想再次添加它。但是,它仍然无法正常工作。它仍在将移动添加到列表中,即使它已经在列表中。
【问题讨论】:
-
杀死的时候叫什么,带回来的时候叫什么。其他类的一些代码可能有助于弄清楚它在做什么。
-
顺便说一句,你能用一组动作代替一个列表吗?
-
@9000 我不太清楚你的意思。您是否建议我将其硬编码到 Monster 类中?如果是这样就不行了,因为 Monster 类只是所有怪物的泛型,但并非所有怪物都有相同的攻击。
-
9000 建议 List
移动为 Set 移动,这是一个很好的建议,但不是导致问题的原因 -
我建议你创建一个minimal, self-contained example。这将帮助您自己找到问题或帮助我们查看问题。