Two foreach loop unnecessary?

Hi guys,

Could any one clarify my question below, to me, it looks unnecessary to do 2 foreach loops, at lease in this situation. I cann’t think of a scenario of an object has more than 1 scripts implementing IRaycastable interface. For instance, a hitObj can be either a combat, a pickup or a movement obj, once a cursor hover upon it, it will only show one cursor type because they all exclusive to another. I could not understand why we need an inner foreach loop to get all raycastComponents in one hitObj. Please can anyone assist with my question? Thank you.

        bool InteractWithRaycastableComponent()
        {
            RaycastHit[] hitObjs = Physics.RaycastAll(GetMouseRay(), maxRayDistance);

          foreach (RaycastHit hitObj in hitObjs)
            { 
                IRaycastable[] raycastComponents = hitObj.transform.GetComponents<IRaycastable>();
                foreach (IRaycastable raycastComponent in raycastComponents)
                {  
                    if (raycastComponent.HandleRaycast(this))
                    {
                        ChooseCurser(raycastComponent.GetCursorType());
                        return true;
                    }
                }
            }
}

Could above just simply into 1 foreach loop?


       bool InteractWithRaycastableComponent()
        {
            RaycastHit[] hitObjs = Physics.RaycastAll(GetMouseRay(), maxRayDistance);

            foreach (RaycastHit hitObj in hitObjs)
            {
                IRaycastable raycastComponent= hitObj.transform.GetComponent<IRaycastable>();
                if (raycastComponent== null) continue;

                if (raycastComponent.HandleRaycast(this))
                {
                    ChooseCurser(raycastComponent.GetCursorType());
                }

                return true;
            }
            return false;
        }
 

We want to make sure that we consider all IRaycastables before considering movement.

What you could do is put tags on all of the GameObjects in the scene that are navigatable (the terrain, bridges, stairs, building entrances, etc) and cache any found in the IRaycastable loop for conderation… something like:

List<RaycastHit> navigatableHits = new List<RaycastHit>();

       bool InteractWithRaycastableComponent()
        {
            RaycastHit[] hitObjs = Physics.RaycastAll(GetMouseRay(), maxRayDistance);
            navigatableHits.Clear(); //Reset for this frame
            foreach (RaycastHit hitObj in hitObjs)
            {
                if hitObj.transform.gameObject.CompareTag("Navigatable")
                {
                    navigatableHits.Add(hitObj);
                    continue;
                }
                IRaycastable raycastComponent= hitObj.transform.GetComponent<IRaycastable>();
                if (raycastComponent== null) continue;

                if (raycastComponent.HandleRaycast(this))
                {
                    ChooseCurser(raycastComponent.GetCursorType());
                }

                return true;
            }
            if(navigatableHits.Count>0)
            {
                  //do movement code here using navigatableHits[0]
            }
            return false;
        }

Thank you for your prompt replay, Brian. I’ll have a study on this.

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.

Privacy & Terms