Unity3d Unity仅在碰撞后向用户添加一次点

Unity3d Unity仅在碰撞后向用户添加一次点,unity3d,collision,Unity3d,Collision,所以我正准备创建我的第一个游戏,我刚刚完成了C语言的课程,所以如果我使用了错误的接口之类的东西,我很抱歉。但是,对于我的问题,;我正在尝试不同的东西,看看什么是有效的。我创造了一枚硬币和一个玩家。硬币的工作原理是它应该的,但是有时当我收集它时,它会给我两倍于它应该得到的分数。硬币的价值是15,有时当我收集一枚硬币时,它会加15分,其他时候它会加30分。我如何防止这种情况发生 这是我的密码: 硬币控制器类别: public class CoinController : MonoBehaviour,

所以我正准备创建我的第一个游戏,我刚刚完成了C语言的课程,所以如果我使用了错误的接口之类的东西,我很抱歉。但是,对于我的问题,;我正在尝试不同的东西,看看什么是有效的。我创造了一枚硬币和一个玩家。硬币的工作原理是它应该的,但是有时当我收集它时,它会给我两倍于它应该得到的分数。硬币的价值是15,有时当我收集一枚硬币时,它会加15分,其他时候它会加30分。我如何防止这种情况发生

这是我的密码:

硬币控制器类别:

public class CoinController : MonoBehaviour, IEconomy {
    private int MoneyValue;

    void Start () {
        MoneyValue = 15;
    }

    void Update () {

    }

    void OnTriggerEnter(Collider col) {
        if (col.CompareTag("Player")) {
            Destroy(transform.gameObject);
            Value();
        }
    }

    public int Value() {
        return EconomyController.Money += MoneyValue;
    }
}
经济总监:

public class EconomyController : MonoBehaviour{
    public static int Money;

    void Start() {
        Money = 0;
    }
}
经济界面:

public interface IEconomy {
    int Value();
}

我想指出一些关于您的代码的事情:

声明变量时的一个良好做法是使用lowerCamelCase:

thisIsLowerCamelCase
ThisIsNot
这是一种变量名约定,在编程中主要用于区分
方法和类
变量

我注意到的另一件事是,您的“Money”变量是
静态的
,并且它仍在
控制器
上更新。我将这个变量设置为私有int变量,并使用setter来更新它。考虑到这一点。。。您是否尝试过使用Debug.Log检查OnTriggerEnter在销毁对象之前是否触发了两次

简单地写下:

Debug.Log ("This should only happen once!");
玩游戏。如果您的控制台显示此消息两次,则此触发器将被调用两次。您可能注意到的另一件事是,在调用
Destroy(transform.gameObject)
之后,您正在调用
Value()
方法

我会这样做:

public class CoinController : MonoBehaviour{

    private int moneyValue = 15;
    private EconomyController economyController;

    void Start (){
        economyController = FindObjectOfType (typeof (EconomyController)) as EconomyController;
    }

    void OnTriggerEnter (Collider col) {
        if (col.CompareTag("Player")) {
            AddValue();
        }
    }

    public int AddValue() {
        EconomyController.money += moneyValue; //Option one.
        EconomyController.AddMoney (moneyValue) ; //Option two.
        DestroyGameObject ();
    }

    private void DestroyGameObject (){
        Destroy(transform.gameObject);
    }
}

使用干净代码原则,选项2使用在EconomyController类中创建的public void函数来更改私有变量。

我想指出有关代码的一些内容:

声明变量时的一个良好做法是使用lowerCamelCase:

thisIsLowerCamelCase
ThisIsNot
这是一种变量名约定,在编程中主要用于区分
方法和类
变量

我注意到的另一件事是,您的“Money”变量是
静态的
,并且它仍在
控制器
上更新。我将这个变量设置为私有int变量,并使用setter来更新它。考虑到这一点。。。您是否尝试过使用Debug.Log检查OnTriggerEnter在销毁对象之前是否触发了两次

简单地写下:

Debug.Log ("This should only happen once!");
玩游戏。如果您的控制台显示此消息两次,则此触发器将被调用两次。您可能注意到的另一件事是,在调用
Destroy(transform.gameObject)
之后,您正在调用
Value()
方法

我会这样做:

public class CoinController : MonoBehaviour{

    private int moneyValue = 15;
    private EconomyController economyController;

    void Start (){
        economyController = FindObjectOfType (typeof (EconomyController)) as EconomyController;
    }

    void OnTriggerEnter (Collider col) {
        if (col.CompareTag("Player")) {
            AddValue();
        }
    }

    public int AddValue() {
        EconomyController.money += moneyValue; //Option one.
        EconomyController.AddMoney (moneyValue) ; //Option two.
        DestroyGameObject ();
    }

    private void DestroyGameObject (){
        Destroy(transform.gameObject);
    }
}

使用干净代码原则,选项2使用在EconomyController类中创建的公共void函数来更改私有变量。

我的直觉告诉我,您当时可能正在收集两枚硬币。我不确定你是如何设置硬币的,但我以前也遇到过类似的问题


想象一个蛇的游戏。假设你已经对它进行了编程,一旦你吃了一个正方形,你就可以在一个随机的位置创建一个新的正方形。有可能新的方块会出现在蛇里面,因此它会立即被吃掉。这可能就是为什么它只在某些时候发生

我的直觉告诉我,你当时可能正在收集两枚硬币。我不确定你是如何设置硬币的,但我以前也遇到过类似的问题


想象一个蛇的游戏。假设你已经对它进行了编程,一旦你吃了一个正方形,你就可以在一个随机的位置创建一个新的正方形。有可能新的方块会出现在蛇里面,因此它会立即被吃掉。这可能就是为什么它只在某些时候发生

在销毁碰撞器之前,请尝试禁用碰撞器。 销毁一个游戏对象不是即时的,而且(令人烦恼的)很容易触发多次

void OnTriggerEnter(Collider col) {
     if (col.CompareTag("Player")) {
         // Pseudo Code: GetComponent<TheColliderItIs>().Enabled = false;
         Value();
         Destroy(transform.gameObject);
     }
 }
void ontriggenter(对撞机列){
如果(col.CompareTag(“玩家”)){
//伪代码:GetComponent().Enabled=false;
Value();
销毁(转换游戏对象);
}
}

在销毁碰撞器之前,请尝试禁用碰撞器。 销毁一个游戏对象不是即时的,而且(令人烦恼的)很容易触发多次

void OnTriggerEnter(Collider col) {
     if (col.CompareTag("Player")) {
         // Pseudo Code: GetComponent<TheColliderItIs>().Enabled = false;
         Value();
         Destroy(transform.gameObject);
     }
 }
void ontriggenter(对撞机列){
如果(col.CompareTag(“玩家”)){
//伪代码:GetComponent().Enabled=false;
Value();
销毁(转换游戏对象);
}
}

我还没有生成硬币并将其随机放置在游戏中的脚本,我在统一性方面还没有那么先进,所以我自己手动将硬币放置在游戏中。在这种情况下,可能是硬币相互堆叠。如果你在添加硬币,购买复制和移动,你通常可以将一个硬币放在另一个上面。我使用的是硬币预制件,这会导致我遇到的问题吗?当场景运行时,硬币已经在那里了,或者它们是在第一次运行场景时生成的?我还没有生成硬币并将其随机放置在游戏中的脚本,我在统一性方面还没有那么先进,所以我自己手动将硬币放置在游戏中。在这种情况下,可能是硬币相互堆叠。如果您添加硬币,请购买复制和移动,您通常可以将一个硬币放在另一个上面。我使用的是硬币预制件,这会导致我遇到的问题吗?场景运行时硬币已经存在,还是在场景首次运行时生成的?