- Home /
How to see an enemy from certain distance and change texture
I need my character to be able to spot an enemy and when he is within 15 units of radius he will change texture. I have tried many different ways but they either do not work because of other scripts going over or not working at all. This is a 2d game btw. I'm using this script.
public float movementSpeed = 5;
public float jumpHeight = 10;
float verticalVelocity = 0;
CharacterController cc;
public int MaxHealth = 100;
public int CurHealth = 100;
void Start () {
//Screen.lockCursor = true;
cc = GetComponent <CharacterController>();
}
void Update () {
AddjustCurrentHealth(0);
//movement
float sideSpeed = Input.GetAxis ("Horizontal") * movementSpeed;
if (cc.isGrounded && Input.GetButtonDown ("Jump")) {
verticalVelocity = jumpHeight;
BroadcastMessage ("jump", SendMessageOptions.DontRequireReceiver);
}else{
if(cc.isGrounded && CurHealth > 1){
BroadcastMessage ("happy", SendMessageOptions.DontRequireReceiver);
}else{
if(cc.isGrounded && CurHealth < 1){
die ();
}
}
}
verticalVelocity += Physics.gravity.y * Time.deltaTime;
Vector3 speed = new Vector3 (sideSpeed, verticalVelocity, 0);
speed = transform.rotation * speed;
cc.Move (speed * Time.deltaTime);
}
void AddjustCurrentHealth(int Adj){
CurHealth += Adj;
if (CurHealth < 0)
CurHealth = 0;
if (CurHealth > MaxHealth)
CurHealth = MaxHealth;
if (MaxHealth < 1)
MaxHealth = 1;
}
void getHit(){
CurHealth -= 20;
}
void die(){
BroadcastMessage ("dead", SendMessageOptions.DontRequireReceiver);
}
Answer by Sundar · Mar 16, 2014 at 05:16 PM
Do a simple distance check using Vector3.sqrMagnitude( check out this link for more info on why sqrMagnitude https://docs.unity3d.com/Documentation/ScriptReference/Vector3-sqrMagnitude.html ) for spotting enemy within 15 unit radius like
void Update()
{
.
.
.
if( ( enemy.position - transform.position ).sqrMagnitude < 15.0f x 15.0f )
{
Print( enemy is within range 15 unit);
// do Raycast for visual if needed
// change players texture and other necessary actions here
}
.
.
.
}
This worked but only when I am jumping. I need it to be when jumping and grounded.
void Update () {
if((enemy.position - transform.position ).sqr$$anonymous$$agnitude < 15.0f * 15.0f ) {
Broadcast$$anonymous$$essage ("angry", Send$$anonymous$$essageOptions.DontRequireReceiver);
}
AddjustCurrentHealth(0);
//movement
float sideSpeed = Input.GetAxis ("Horizontal") * movementSpeed;
if (cc.isGrounded && Input.GetButtonDown ("Jump")) {
verticalVelocity = jumpHeight;
Broadcast$$anonymous$$essage ("jump", Send$$anonymous$$essageOptions.DontRequireReceiver);
}else{
if(cc.isGrounded && CurHealth > 1){
Broadcast$$anonymous$$essage ("happy", Send$$anonymous$$essageOptions.DontRequireReceiver);
}else{
if(cc.isGrounded && CurHealth < 1){
die ();
}
}
}
verticalVelocity += Physics.gravity.y * Time.deltaTime;
Vector3 speed = new Vector3 (sideSpeed, verticalVelocity, 0);
speed = transform.rotation * speed;
cc.$$anonymous$$ove (speed * Time.deltaTime);
}
Yes it won't work if you are not jumping because you change player's angry state to happy state immediately when player not jumping. You can use a Boolean to avoid this change. There are better ways to do it for example using an enum for all player states. But I will use Boolean to make it work.
bool angryState = false;
void Update () {
if((enemy.position - transform.position ).sqr$$anonymous$$agnitude < 15.0f * 15.0f ) {
if( !angryState) Broadcast$$anonymous$$essage ("angry", Send$$anonymous$$essageOptions.DontRequireReceiver);
angryState = true;
}
else angryState = false;
AddjustCurrentHealth(0);
//movement
float sideSpeed = Input.GetAxis ("Horizontal") * movementSpeed;
if (cc.isGrounded && Input.GetButtonDown ("Jump")) {
verticalVelocity = jumpHeight;
Broadcast$$anonymous$$essage ("jump", Send$$anonymous$$essageOptions.DontRequireReceiver);
}else{
if(cc.isGrounded && CurHealth > 1){
if(!angryState)Broadcast$$anonymous$$essage ("happy", Send$$anonymous$$essageOptions.DontRequireReceiver);
}else{
if(cc.isGrounded && CurHealth < 1){
die ();
}
}
}
verticalVelocity += Physics.gravity.y * Time.deltaTime;
Vector3 speed = new Vector3 (sideSpeed, verticalVelocity, 0);
speed = transform.rotation * speed;
cc.$$anonymous$$ove (speed * Time.deltaTime);
}
This worked almost perfect so I added the same if(!angryState) before my jump message and bam perfect. Thank you very much and I will definitely have a look at enum or anything to make it look cleaner.
Answer by Jeremy2300 · Mar 16, 2014 at 03:53 PM
Does the enemy need to be in front of the player, or just within a certain radius?
You could look at Spherecast if it's the radius and Raycast or Linecast if in front is necessary.
Put a certain layer on the enemy and then look if a hit is within that range (either by casting out a certain distance, or looking at the distance value on a confirmed hit)
It needs to be within a radius.
I had a look at that Spherecast but did not understand very much. Tried attaching it but nothing happened.
Your answer
Follow this Question
Related Questions
Player damage stops working over time 0 Answers
Why enemy animation messes up the player ? 0 Answers
enemy detect player then attack - c# 1 Answer
Assigning UV Map to model at runtime 0 Answers
Make player face different enemies with the same tag 0 Answers