This topic contains 5 replies, has 2 voices, and was last updated by  James.AVN 1 year, 2 months ago.

Viewing 6 posts - 1 through 6 (of 6 total)
  • Author
    Posts
  • #38607

    James.AVN
    Participant

    Hi everyone,

    I’m using the take “Cover” feature of SC. What I want to achieve is my AI will switch to a new cover spot after a period of time. However, from time to time, I encounter a problem that 2 AI stand at the same cover spot.

    What I did was drag in the “Cover” prefab, then reuse the part of the tree under ‘attackBehavior == “cover”‘ for my AI. I checked the cover “AIObjective”, the “Occupant” variable got assigned to the AI that is at that spot.

    What could be the problem and how do I fix it? Thanks a lot

    James

    #38618

    Sigil
    Keymaster

    Could you post a screen shot of your behavior tree, maybe while it is running so we can see what is happening there? Might need two screenshots, one for each of the AI on the same spot.

    I dug through the FindCoverPoint code and I’m having trouble seeing how it could possibly get two AI to the same spot, so perhaps something about the behavior tree is causing this. Something like storing the position of a cover spot, but upon failing to get a new one accidentally using a stored value or something.

    I’ll test some things here as well.

    #38781

    James.AVN
    Participant

    Hi Sigil,

    I was away for a while. Thank you for your help.

    I figure out the problem is that, after switching from the current attackBehaviour (take cover and shoot) to a new attackBehaviour (which doesnt have the “FindCoverPoint” action, the Cover Occupant will be set to null. I think this is due to in the “FindCoverPoint”, when Stop, it Vacate the spot. Hence, this spot become available for other AI to take.

    Can I comment out this Vacate(ai); in the Stop function? would it affect anything?

    Thank you.

    #38789

    Sigil
    Keymaster

    I believe the intent of the FindCoverPoint was for it to continue running as long as you want to hold on to the spot (which is why the Stop frees it up).

    You could change it, and remove the Vacate from the Stop, but then you would need to store that cover spot in your AI memory so that you can vacate it later (with another Custom Action of your own). Definitely doable, but you would have to change the way FindCoverPoint works to get it going.

    I’ll take a look and see if there is an easier way to work it.

    #38793

    James.AVN
    Participant

    Hi Sigil,

    I comment out the “Vacate(ai);” in the Stop function. And modify the FindBestCoverPoint as below. What I’m trying to do is to have the AI move to a new cover point (if there is one). The code below correctly vacate and occupy the AIObjective. However, the AI never moves to a new cover. What would be the problem with my code? Thank you for your help.

    private void FindBestCoverPoint(AI ai)
        {
            if (!CoverVariable.IsValid || !CoverVariable.IsVariable)
                return;
            //We don't actually have to have an enemy.  We can choose cover points that are simply near ourselves.
            Vector3 tEnemyPosition = ai.Kinematic.Position;
            if (EnemyVariable.IsValid && EnemyVariable.IsVariable)
            {
                //using a MoveLookTarget lets us automatically convert between gameObject, Vector3, etc., when getting
                //a position from AI memory
                MoveLookTarget tTarget = MoveLookTarget.GetTargetFromVariable(ai.WorkingMemory, EnemyVariable.VariableName, ai.Motor.CloseEnoughDistance);
                if (tTarget.IsValid)
                    tEnemyPosition = tTarget.Position;
            }
            //Cover points should be marked with the "cover" tactical aspect
            _coverSensor.Sense("cover", RAINSensor.MatchType.ALL);
    	//**********Modified**********
    	AIObjective previousCoverSpot = null;
    	Vector3 previousCoverAspect = ai.Kinematic.Position;;
    	//**********Modified**********
            //Default cover point is our own position
            float bestCost = float.MaxValue;
            Vector3 tCoverPosition = ai.Kinematic.Position;
            for (int i = 0; i < _coverSensor.Matches.Count; i++)
            {
                TacticalAspect tCandidateAspect = _coverSensor.Matches[i] as TacticalAspect;
                if (tCandidateAspect == null)
                    continue;
                //Cover points are AIObjectives, which are objects that allow AI to "occupy" them
                AIObjective tObjective = tCandidateAspect.Entity.Form.GetComponent<AIObjective>();
                //Skip occupied cover points
    	   //**********Modified**********
    	   if((tObjective != null) && (tObjective.IsOccupied) && (tObjective.Occupant == ai.Body)){
    		previousCoverSpot = tObjective;
    		previousCoverAspect = tCandidateAspect.Position;
    		continue;
    	   }
    	   if ((tObjective == null) || (tObjective.IsOccupied && tObjective.Occupant != ai.Body))
                    continue;
    	//**********Modified**********
                //Our cost function gives 50% more weight to points near the enemy
                //But then also adds in the AI distance to the point
                float tCost = 1.5f * Vector3.Distance(tEnemyPosition, tCandidateAspect.Position) + Vector3.Distance(ai.Kinematic.Position, tCandidateAspect.Position);
                if (tCost < bestCost)
                {
                    _currentCoverPoint = tObjective;
                    tCoverPosition = tCandidateAspect.Position;
                    bestCost = tCost;
                }
            }
            //If we found a cover point, then occupy it
    	//**********Modified**********
            if (_currentCoverPoint != null){
    		if(previousCoverSpot != null)
    			previousCoverSpot.Vacate(ai.Body);
                _currentCoverPoint.Occupy(ai.Body);
    	}else if(previousCoverSpot != null){
    	    tCoverPosition = previousCoverAspect;
    	    previousCoverSpot.Occupy(ai.Body);
    	}
    	//**********Modified**********
            //Set the cover position in AI memory
            ai.WorkingMemory.SetItem<Vector3>(CoverVariable.VariableName, tCoverPosition);
        }
    • This reply was modified 1 year, 2 months ago by  James.AVN.
    #38795

    James.AVN
    Participant

    Hi,

    I manage to figure it out. I never comment the Vacate(ai); inside Start() so that the current position is still within the new cover spots list, which has the best cost also. I comment it out and it works as I wanted. Thanks.

Viewing 6 posts - 1 through 6 (of 6 total)

You must be logged in to reply to this topic.