Arcana Affinity
Arcana Affinity

Reputation: 307

Creating dictionary and returning values

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();
}

So, What I'm trying to achieve here is when objects enter this trigger collect certain variables(in this case it's drag and angularDrag) and store it to return their stored values on OnTriggerExit. Also I'm trying to do this because I'd like to change these values here on OnTriggerEnter and make them return to original afterwise.

However, I'm not getting all the objects all the values back, but only one of them gets it back.

Edit : Seemed my explanation was poorer than I thought, so let me try again. This question was occurred by a simple mechanic I'm trying to implement to manipulate a rigidBody's drag and angularDrag. However, there can be numerous gameObjects in this trigger at the same time and gameObjects inside it have different value of drag and angularDrag I saw it necessary to store them temporarily and return them on OnTriggerExit. Where I am at now is I'm returning one gameObject its 'old values' after manipulation mechanic happening finishes, but the rest are stuck in that state without getting their 'original values' restored.

Upvotes: 0

Views: 93

Answers (2)

Programmer
Programmer

Reputation: 125265

There several issues in your code.

1.Don't forget to have if (coll.gameObject.GetComponent<InteractiveObjectType>() != null) in the OnTriggerExit too just like you did in the OnTriggerEnter function.

2.I noticed you are using using different Dictionaries just to store the drag and the angular drag. You don't have to do this. Just use one dictionary and a struct that holds the drag and angular drag values.

It should look like something below:

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.You don't have to clear the Dictionary. You don't even have to loop over it. Just remove each individual one detected in the OnTriggerExit function if the TryGetValue function returns true.

This is what the whole code should look like with the 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);
        }
    }
}

Note that DragInfo is a struct not class. Make sure to keep it as a struct to avoid allocating memory each time.

Upvotes: 2

Pluto
Pluto

Reputation: 4061

To get the stored values just use the gameObject as the key:

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

Use dragDic.Remove(targetGo) and angDic.Remove(targetGo) to remove the gameObject from the dictionaries.

Upvotes: 1

Related Questions