JavaScript - Reset Characters Position

I’m building a single player, side-scrolling children’s game, where the main objective is to collect rainwater and drop it off to the houses needing it the most - for recycling, washing the car, gardening, on food crops etc.

I have this script that controls the main character (Chelsea):

var normalSpeed:float=10.0;

var playerLives:int;
static var bucketLevel:int;
static var tankLevel:int;

private var speed:float=normalSpeed;
var runSpeed:float=12.0;
private var jumpSpeed:float=speed*1.7;
var gravity:float=35.0;
private var walkTime:int=0;
private var moveDirection:Vector3=Vector3.zero;
static var grounded:boolean=false;
private var controller:CharacterController;
private var flags:CollisionFlags;
private var tr:int=90;
var gotHit:boolean=false;

private var startPos:Vector3;

function Start(){
	animation.wrapMode=WrapMode.Loop;
	animation["run"].layer=-1;
	animation["walk"].layer=-1;
	animation["idle 4"].layer=-1;
	animation.SyncLayer(-1);
	
	animation["jump"].layer=10;
	animation["jump"].wrapMode=WrapMode.Once;
	animation["587"].layer=10;
	animation["587"].wrapMode=WrapMode.Once;
	animation.SyncLayer(10);
	
	animation.Stop();
	animation.Play("idle 4");
	startPos=transform.position;
	}
	
		
function FixedUpdate () {
	if(!gotHit){
	if (grounded){
		moveDirection=new Vector3(Input.GetAxis("Horizontal"),0,0);
		moveDirection*=speed;
		if(Input.GetButton("Jump")){
			moveDirection.y=jumpSpeed;

			animation.CrossFade("jump");
		}
	}else{
		moveDirection=new Vector3(Input.GetAxis("Horizontal"),moveDirection.y/speed,0);
		moveDirection*=speed;
		
	}
	
	moveDirection.y-=gravity*Time.deltaTime;
	controller=GetComponent(CharacterController);
	flags=controller.Move(moveDirection*Time.deltaTime);
	
	grounded=(flags & CollisionFlags.CollidedBelow) !=0;
	
	if(moveDirection.x>0){
		tr=90;
	}else if(moveDirection.x<0){
		tr=270;
	}
	
	transform.eulerAngles.y-=(transform.eulerAngles.y-tr)/5;
	
	if(Input.GetAxis("Horizontal")>.2 || Input.GetAxis("Horizontal")<-.2){
		if(walkTime>40){
			animation.CrossFade("run");
			speed=runSpeed;
		}else{
			walkTime++;
			animation.CrossFade("walk");
			speed=normalSpeed;
		}
		jumpSpeed=speed*1.7;
		
	}else{
		walkTime=0;
		animation.CrossFade("idle 4");
	}
	
	if(tankLevel >=500){
		tankLevel = 0;
		Application.LoadLevel(3); 
	}
	
	if(playerLives <=0){
			}
	}
}

function OnGUI(){
	GUI.Label(Rect(10,345,250,100),"Bucket:");
	//GUI.Label(Rect(10,360,250,100),"Water Tank:");
	GUI.Label(Rect(10,375,250,100),"Lives: " + playerLives);
	
}

function OnControllerColliderHit(hit: ControllerColliderHit) {
	if (hit.gameObject.tag == "SplashTheFish" && gotHit==false) {
	gotHit = true;
	
	playerLives --;
	

	animation.CrossFade("587");
	GameObject.Find("Cloud/CloudHit").GetComponent(CatchWater).resetWaterCaught();
	Invoke("revive",3);
	
	}
}
function revive(){
	if(playerLives>0){
		gotHit=false;
		transform.position=startPos;
	
	}else{
		Application.LoadLevel(2);
	
	}
	
}

function reviveIn3Seconds(){
	Invoke("revive",3);
}
@script RequireComponent(CharacterController)

And this other script that controls the second character (Splash):

private var speed:float=8;
private var minX:int=331;
private var maxX:int=412;
private var targetX:int;
private var controller: CharacterController;
private var myZ:float;

private var gotHit:boolean=false;

private var startPos:Vector3;

var playerLives:int;


function Start(){
	targetX=Random.Range(minX,maxX);
	controller=GetComponent(CharacterController);
	myZ=transform.position.z;
	

}

function Update () {
	var targetPos=Vector3(targetX,transform.position.y,transform.position.z);
	transform.LookAt(targetPos);
	transform.position.z=myZ;
	
	var forward = transform.TransformDirection(Vector3.forward);
	controller.SimpleMove(forward*speed);
	//transform.position=Vector3.Lerp(transform.position,targetPos,Time.deltaTime*smooth);
	if(Vector3.Distance(transform.position,targetPos)<3){
		
		targetX=Random.Range(minX,maxX);
	}
}

function OnControllerColliderHit(hit: ControllerColliderHit) {
	if (hit.gameObject.tag == "Player" && gotHit==false) {
		gotHit = true;
		if(hit.gameObject.GetComponent(ChelseaController).gotHit==false) {
	hit.gameObject.GetComponent(ChelseaController).gotHit = true;
	
	hit.gameObject.GetComponent(ChelseaController).playerLives=hit.gameObject.GetComponent(ChelseaController).playerLives-1;
	
	GameObject.Find("Cloud/CloudHit").GetComponent(CatchWater).resetWaterCaught();
	Invoke("revive",3);
		}
	}
}


function revive(){
	if(playerLives>0){
		gotHit=false;
		transform.position=startPos;
	
	}
}

function reviveIn3Seconds(){
	Invoke("revive",3);
}

In the game, the first character (Chelsea) has to avoid bumping into the second character (Splash) while she’s on her mission, or she’ll spill over all of the water she’s collected and the player will lose a life out of the 3 that they have.

Each character moves left and right along the x-axis, the only difference is Chelsea has a set position in the game, always starting next to her home in each scene and is controlled by the player who would need to jump over Splash. As for Splash, he moves randomly (between 331 and 412) and is controlled by the computer.

The problem is when Chelsea collides with Splash and loses all of the water she’s collected, both her and Splash need to be “reset” back to their starting positions in the game. While Chelsea’s reset position is working however, Splash’s isn’t.

How would I be able to do the same thing with him? I’m fairly new to javascript and this is my first Unity3D project so please be gentle.

Any help or advice in getting this to work would be really appreciated.

Like with Chelsea’s script, you need

startPos=transform.position;

in Splash’s

function Start()

That is hopefully all that needs adding, though I haven’t tested the scripts in unity so thats not a promise :wink:

Scribe

Luckily this should be easy to fix… you need to set the var “playerLives” of SPLASH to reflect that of Chelsea… lets do it right where the lives are changed for now, in the Collision function (on the SPLASH script):

function OnControllerColliderHit(hit: ControllerColliderHit) {
    if (hit.gameObject.tag == "Player" && !gotHit) {
       gotHit = true;
       // Since you use it several times, store a reference to the chelsea script
       var chelsea : ChelseaController = hit.gameObject.GetComponent(ChelseaController);
       if(!chelsea.gotHit) {
           chelsea.gotHit = true;   
           chelsea.playerLives-=1;  // shorthand, means the same thing, subtract one
           playerLives = chelsea.playerLives; // TRACK THE PLAYER LIVES!!!
          GameObject.Find("Cloud/CloudHit").GetComponent(CatchWater).resetWaterCaught();
          Invoke("revive",3);
       }
    }
}

The other issue here is that you are doing the SAME THING HERE as in the other collision script. You really shouldn’t do this from BOTH scripts.
So let’s move the stuff from the CHELSEA script collision function to SPLASH"S script as well, so it’s all handled in one place… NOW our final function is:

function OnControllerColliderHit(hit: ControllerColliderHit) {
    if (hit.gameObject.tag == "Player" && !gotHit) {
       gotHit = true;
       // Since you use it several times, store a reference to the chelsea script
       var chelsea : ChelseaController = hit.gameObject.GetComponent(ChelseaController);
       if(!chelsea.gotHit) {
           chelsea.gotHit = true;   
           chelsea.playerLives-=1;  // shorthand, means the same thing, subtract one
           playerLives = chelsea.playerLives; // TRACK THE PLAYER LIVES!!!
          GameObject.Find("Cloud/CloudHit").GetComponent(CatchWater).resetWaterCaught();
          Invoke("revive",3);              
          hit.gameObject.animation.CrossFade("587");
          chelsea.Invoke("revive",3);
       }
    }
}

you can delete the other script’s entire OnControllerColliderHit function now, and this way we know exactly what’s doing what…

This should do it for you, I think

EDIT:

As @Daniel’s answer rightly points out, you will also want to store the correct position in “startPosition”, to get the exact results desired…