Help with conquest zone capture

Hey guys, first time poster so I’m not sure if this is the right place to post this. Anyway, I’m working on a singleplayer RTS/FPS conquest type game (mostly for learning purposes) in which two factions are battling for control of a certain location.

I’ve been working on the actual zone capture mechanics and I’ve hit somewhat of a logic roadblock (not sure if it’s because it’s too early in the morning and I’ve only just started drinking a cup of coffee lol). What I’m trying to achieve at the moment is the having the flag change position as the control of the location begins to shift from one team to the other.

So let’s say that Team A is the current controller of the location and Team B is capturing it, and the flag’s max height is 10 on y axis and it’s lowest is 1; I want the flag to begin moving downwards from max height to min height as Team B’s capture % goes up from 0% to 50% at which point the flag will switch textures and then begin to ascend again as Team B’s capture % goes up from 50% to 100%. Similar to how Bf 4 works. So if you guys can walk me through the logic of the best way to achieve this that would be awesome!

I’ve posted my current script below. Not sure if this is the most optimal way of going about it so any suggestions and advice would be much appreciated.

using UnityEngine;
using System.Collections;

public class ConquestZoneTest : MonoBehaviour {

	public GameObject flag;
	public Texture2D flagTeamA;
	public Texture2D flagTeamB;

	public Light flagLight;
	public float lightMaxIntensity = 5.0f;
	public float lightMinIntensity = 0.0f;
	public float lightChangeMargin = 0.2f;
	public float lightSwitchRate = 1.0f;

	public float captureRate = 2.0f;

	public bool teamACapturing = false;
	public bool teamBCapturing = false;
	public bool strategicPointContested = false;

	public bool underAControl = false;
	public bool underBControl = false;

	public float teamACapPercent = 0.0f;
	public float teamBCapPercent = 0.0f;

	private MeshRenderer flagRenderer;
	private float targetLightIntensity;

	void OnEnable() {
		
		flagRenderer = flag.GetComponent<MeshRenderer> ();
		flagLight.intensity = 0.0f;
	}

	void Update () {

		if (teamACapturing == true && strategicPointContested == false) {

			teamACapPercent += Time.deltaTime * captureRate;
			teamBCapPercent = 100 - teamACapPercent;
		}

		if (teamBCapturing == true && strategicPointContested == false) {
		
			teamBCapPercent += Time.deltaTime * captureRate;
			teamACapPercent = 100 - teamBCapPercent;
		}

		if (teamACapturing == true && teamBCapturing == true) {

			teamACapPercent = teamACapPercent;
			teamBCapPercent = teamBCapPercent;
			strategicPointContested = true;
		} else {
		
			strategicPointContested = false;
		}

		if (teamACapPercent >= 100) {
		
			teamACapPercent = 100;

			if (underAControl == false) {

				flagRenderer.material.mainTexture = flagTeamA;
				underBControl = false;
				underAControl = true;
			}
		}

		if (teamACapPercent <= 0) {
		
			teamACapPercent = 0;
		}

		if (teamBCapPercent >= 100) {

			teamBCapPercent = 100;

			if (underBControl == false) {

				flagRenderer.material.mainTexture = flagTeamB;
				underAControl = false;
				underBControl = true;
			}
		}

		if (teamBCapPercent <= 0) {
		
			teamBCapPercent = 0;
		}

		if ((teamACapPercent > 0 && teamACapPercent < 100) || (teamBCapPercent > 0 && teamBCapPercent < 100) || strategicPointContested) {
		
			flagLight.intensity = Mathf.Lerp (flagLight.intensity, targetLightIntensity, lightSwitchRate * Time.deltaTime);

			CheckLightTargetIntensity ();
		} else {

			flagLight.intensity = Mathf.Lerp (flagLight.intensity, 0.0f, lightSwitchRate * Time.deltaTime);
		}
			
	}

	void CheckLightTargetIntensity(){

		if (Mathf.Abs (targetLightIntensity - flagLight.intensity) < lightChangeMargin) {
			if (targetLightIntensity == lightMaxIntensity)
				targetLightIntensity = lightMinIntensity;
			else
				targetLightIntensity = lightMaxIntensity;
		}
	}
}

If there are only 2 teams you could have the value be between -10 and 10 (or whatever value you set). One side subtracts points away from the conquest zone and the other adds points to the zone.

I am not sure how you are adding points, but it could be achieved with a trigger that checks to see the unit’s faction based off tag/layer/script/etc.

if(teamA && !teamB){
conquestPoints += Time.deltaTime * capSpeed;
}else if(teamB && !teamA){
conquestPoints -= Time.deltaTime * capSpeed;
}else if (!teamA  && !teamB){
//noone capping
}else{
//its contested
}

if(conquestPoints > maxPoints){
conquestPoints  = maxPoints;
}
if(conquestPoints < -maxPoints){
conquestPoints  = -maxPoints;
}

if(conquestpoints > 0){
//set the flag to team A's color
}else if(conquestpoints < 0){
//set flag to team B's color
}else{
//its 0, set to a neutral color
}

Now we can get the cap percentage. Using Mathf.Abs will give us a positive value even if we plug in a negative

capPercent = Mathf.Abs(conquestPoints) / maxPoints;

and then when you want to change the height of the flag (i think thats what you want, so it floats up and down) I would make your flag a child of the conquest point game object, that way you can take advantage of localPosition (if your conquest points vary in height on the terrain). Saves some position calculation headaches. Just place the conquest point gameobject at the lowest point on the terrain.

I would lerp it to this new position.

flag.localPosition= Vector3.Lerp(flag.localPosition, new Vector3(0 , capPercent * maxFlagHeight, 0), Time.deltaTime * flagSpeed);