Reputation: 307
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
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
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