创建字典并返回值

时间:2017-09-01 02:54:20

标签: c# unity3d

public float slowAmount;
public float effectDuration = 3f;

private Dictionary<GameObject, float> dragDic = new Dictionary<GameObject, float>();
private Dictionary<GameObject, float> angDic = new Dictionary<GameObject, float>();

private Dictionary<GameObject, KeyValuePair<float, float>> DragDic = new Dictionary<GameObject, KeyValuePair<float, float>>();

void OnTriggerEnter(Collider coll)
{
    if (coll.gameObject.GetComponent<InteractiveObjectType>() != null)
    {
        GameObject targetGo = coll.gameObject;
        Rigidbody targetRB = targetGo.GetComponent<Rigidbody>();

        dragDic.Add(targetGo, targetRB.drag);
        angDic.Add(targetGo, targetRB.angularDrag);
    }

        **// drag manipulation happens here**

}

void OnTriggerExit(Collider coll)
{
    GameObject targetGo = coll.gameObject;
    Rigidbody targetRB = targetGo.GetComponent<Rigidbody>();


    for (int i = 0; i < dragDic.Count; i++)
    {
        foreach (float target in dragDic.Values)
        {
            targetRB.drag = target;
        }
    }

    for (int i = 0; i < angDic.Count; i++)
    {
        foreach (float target in angDic.Values)
        {
            targetRB.angularDrag = target;
        }
    }

    dragDic.Clear();
    angDic.Clear();
}

所以,我在这里尝试实现的是当对象进入此触发器时收集某些变量(在这种情况下是它的drag和angularDrag)并存储它以在OnTriggerExit上返回它们的存储值。我也试图这样做,因为我想在OnTriggerEnter上更改这些值,然后让它们在之后返回原始状态。

但是,我没有得到所有值的所有对象,但只有其中一个得到它。

编辑:看来我的解释比我想象的要差,所以让我再试一次。 这个问题是由一个简单的机制发生的,我试图实现操纵刚体的拖拽和angularDrag。但是,同时在此触发器中可以有许多gameObjects,并且其中的gameObjects具有不同的drag和angularDrag值我认为有必要临时存储它们并将它们返回到OnTriggerExit上。我现在所处的位置是我将一个游戏对象归还其旧的价值观#39;在操纵机制发生完成之后,其余部分都停留在那个状态而没有得到他们的原始价值观&#39;恢复。

2 个答案:

答案 0 :(得分:2)

您的代码中存在多个问题。

1 。忘记在if (coll.gameObject.GetComponent<InteractiveObjectType>() != null)中忘记OnTriggerExit,就像在OnTriggerEnter函数中一样。

2 。我注意到您正在使用不同的词典来存储拖动和角度拖动。你不必这样做。只需使用一个字典和一个包含拖动和角度拖动值的struct

它应该如下所示:

public struct DragInfo
{
    public float drag;
    public float angularDrag;

    //Initialize the variables
    public DragInfo(float drag, float angularDrag)
    {
        this.drag = drag;
        this.angularDrag = angularDrag;
    }
}

3 。您不必清除词典。你甚至不必在它上面循环。如果OnTriggerExit函数返回true,只需删除TryGetValue函数中检测到的每个个体。

使用DragInfo struct:

,这就是整个代码的样子
public struct DragInfo
{
    public float drag;
    public float angularDrag;

    //Initialize the variables
    public DragInfo(float drag, float angularDrag)
    {
        this.drag = drag;
        this.angularDrag = angularDrag;
    }
}

public float slowAmount;
public float effectDuration = 3f;

private Dictionary<GameObject, DragInfo> dragInfo = new Dictionary<GameObject, DragInfo>();

void OnTriggerEnter(Collider coll)
{
    Rigidbody targetRB;

    if (coll.gameObject.GetComponent<InteractiveObjectType>() != null)
    {
        GameObject targetGo = coll.gameObject;
        targetRB = targetGo.GetComponent<Rigidbody>();

        //Create new DragInfo with the current Object 
        DragInfo dragDetail = new DragInfo(targetRB.drag, targetRB.angularDrag);

        //Add it to the Dictionary
        dragInfo.Add(targetGo, dragDetail);
    }

    //drag manipulation happens here**
    //targetRB.drag = ???
    //targetRB.angularDrag = ???
}

void OnTriggerExit(Collider coll)
{
    GameObject targetGo = coll.gameObject;
    Rigidbody targetRB = targetGo.GetComponent<Rigidbody>();

    if (coll.gameObject.GetComponent<InteractiveObjectType>() != null)
    {
        //Where to store retrieved Object
        DragInfo storedDragInfo;

        //Retrieve and Check if the Object exist in the Dictiionry 
        if (dragInfo.TryGetValue(targetGo, out storedDragInfo))
        {
            //Restore the current value of the detected GameObject
            targetRB.drag = storedDragInfo.drag;
            targetRB.angularDrag = storedDragInfo.angularDrag;

            //Remove it from the Dictionary
            dragInfo.Remove(targetGo);
        }
    }
}

请注意,DragInfostruct而不是class。确保将其保留为struct以避免每次都分配内存。

答案 1 :(得分:1)

要获取存储的值,只需使用gameObject作为键:

GameObject targetGo = coll.gameObject;
Rigidbody targetRB = targetGo.GetComponent<Rigidbody>();
if (targetGo.GetComponent<InteractiveObjectType>() != null){
    targetRB.drag = dragDic[targetGo];
    targetRB.angularDrag = angDic[targetGo];
}

使用dragDic.Remove(targetGo)angDic.Remove(targetGo)从词典中删除gameObject。