i want a karlson-esque movement for my game but i cant seem to nail it correctly, i basically want to add a force to the players base velocity just bieng tossed around in the game, like a velocity offset if you will,
for example if the player gets hit by a high velocity cube and tossed back naturally, they should struggle to regain thier stability and kind of come to a gradual halt assuming they are moving in the opposite direction than where they were being tossed, but my method (setting the players velocity) doesnt really work that well for what im trying to achieve, it simply comes to a semi-immediate halt, ive tried interpolation to make a gradual speed increase but input.getaxis and velocity both already somewhat cover that, anything more and the "coming to a halt" part works but movement isnt as snappy as i wish it was, here is my full code (note that i am somewhat of a beginner, ive done coding elsewhere but i just started unity a few weeks ago)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class charactercontroller : MonoBehaviour {
//variables and functions
public float moveSpeed = 7f;
public bool tweening = false;
public bool jumping = false;
public bool reteleporing = false;
public Vector3 smoothedvel;
public Vector3 smoothedvectorweapon;
public float smoothedweaponspeed;
public Vector3 smoothedrotationalvector;
public Quaternion smoothedrotateweapon;
public Vector3 cameraoffset;
public float[] tweeninformation = {3f,5f,6f,7f,8f,9f,10f};
public float[] tweeninformationreverse = {10f,9f,8f,7f,6f,5f,3f};
void Start () {
cameraoffset = new Vector3(0,0,0);
smoothedvel = new Vector3(0,0,0);
smoothedrotateweapon = Quaternion.Euler(0,0,0);
smoothedweaponspeed = 0.1f;
smoothedvectorweapon = new Vector3(0.559f,0,-0.523f);
StartCoroutine(waiter());
}
IEnumerator waiter()
{
while(true)
{
if (new Vector3(Input.GetAxis("Vertical"),0,Input.GetAxis("Horizontal")).magnitude != 0 && Physics.Raycast(transform.position, -Vector3.up, gameObject.GetComponent<Collider>().bounds.extents.y + 0.3f) == true)
{
gameObject.GetComponent<ParticleSystem>().Emit(new ParticleSystem.EmitParams(), 3);
transform.GetChild(0).GetComponent<AudioSource>().pitch = Random.Range(1.0f,1.5f);
transform.GetChild(0).GetComponent<AudioSource>().Play();
}
yield return new WaitForSeconds(0.25f);
}
}
void Update (){
//movement
smoothedrotationalvector = Vector3.Lerp(smoothedrotationalvector, new Vector3(-Input.GetAxis("Vertical"),0,Input.GetAxis("Horizontal")), smoothedweaponspeed);
transform.GetChild(2).GetChild(0).transform.localPosition = Vector3.Lerp(transform.GetChild(2).GetChild(0).transform.localPosition, smoothedvectorweapon, smoothedweaponspeed);
transform.GetChild(2).GetChild(0).transform.localRotation = Quaternion.Lerp(transform.GetChild(2).GetChild(0).transform.localRotation, smoothedrotateweapon, smoothedweaponspeed);
if (new Vector3(Input.GetAxis("Vertical"),0,Input.GetAxis("Horizontal")).magnitude != 0)
{
transform.GetChild(2).transform.LookAt(transform.position + smoothedrotationalvector);
}
if (transform.position.y < -100)
{
reteleporing = true;
}
if (reteleporing == true)
{
transform.position = GameObject.Find("spawnpos").transform.position;
}
if (transform.position.y > 2.4)
{
reteleporing = false;
}
///if (Physics.Raycast(transform.position,transform.forward * Time.deltaTime * Input.GetAxis("Vertical"), gameObject.GetComponent<Collider>().bounds.extents.x + 0.3f) == false && reteleporing == false)
///{
/// transform.Translate(transform.forward * Time.deltaTime * Input.GetAxis("Vertical")* moveSpeed);
///}
///else
///{
// transform.Translate(transform.forward * Time.deltaTime * Input.GetAxis("Vertical")* 1);
//}
//if (Physics.Raycast(transform.position,transform.right * Time.deltaTime * Input.GetAxis("Horizontal"),gameObject.GetComponent<Collider>().bounds.extents.z + 0.3f) == false && reteleporing == false)
//{
// transform.Translate(transform.right * Time.deltaTime * Input.GetAxis("Horizontal")* moveSpeed);
//}
//else
//{
// transform.Translate(transform.right * Time.deltaTime * Input.GetAxis("Horizontal")* 1);
//}
if (reteleporing == false)
{
gameObject.GetComponent<Rigidbody>().velocity = Vector3.Lerp(gameObject.GetComponent<Rigidbody>().velocity,new Vector3(Input.GetAxis("Horizontal") * moveSpeed,gameObject.GetComponent<Rigidbody>().velocity.y,Input.GetAxis("Vertical") * moveSpeed), 0.1f);
}
//if (Physics.Raycast(transform.position, -Vector3.up, gameObject.GetComponent<Collider>().bounds.extents.y + 0.3f) == true)
//{
// gameObject.GetComponent<Rigidbody>().velocity = Vector3.Lerp(gameObject.GetComponent<Rigidbody>().velocity, new Vector3(0,0,0), 0.01f);
//}
//camera controlling
smoothedvel = Vector3.Lerp(smoothedvel, gameObject.GetComponent<Rigidbody>().velocity * 0.1f, 0.1f);
Camera maincam = GameObject. Find("Main Camera"). GetComponent<Camera>();
Vector3 camend = transform.position + new Vector3(Input.GetAxis("Horizontal") * 0.5f,0,0);
maincam.transform.position = transform.position + new Vector3(0, 4, -7f) + cameraoffset;
maincam.transform.LookAt(transform.position + smoothedvel);
//jumping
if (Input.GetKeyDown(KeyCode.Space))
{
if (Physics.Raycast(transform.position, -Vector3.up, gameObject.GetComponent<Collider>().bounds.extents.y + 0.3f) == true)
{
gameObject.GetComponent<Rigidbody>().AddForce(transform.up * 250);
moveSpeed = 9f;
}
}
if (Physics.Raycast(transform.position, -Vector3.up, gameObject.GetComponent<Collider>().bounds.extents.y + 0.3f) == false)
{
moveSpeed = 9f;
jumping = true;
}
else
{
moveSpeed = 7f;
if (jumping == true)
{
jumping = false;
transform.GetChild(1).GetComponent<AudioSource>().Play();
gameObject.GetComponent<ParticleSystem>().Emit(new ParticleSystem.EmitParams(), 4);
StartCoroutine(jumpanimwait());
IEnumerator jumpanimwait()
{
yield return new WaitForSeconds(0.2f);
}
}
}
//weapon
if (Input.GetKeyDown(KeyCode.Mouse0))
{
StartCoroutine(gunwait());
IEnumerator gunwait()
{
smoothedweaponspeed = 0.5f;
smoothedvectorweapon = new Vector3(-0.021f,0.172f,-0.523f);
smoothedrotateweapon = Quaternion.Euler(0,0,33.318f);
transform.GetChild(2).GetChild(0).GetComponent<ParticleSystem>().Emit(new ParticleSystem.EmitParams(), 2);
GameObject clone = Instantiate(GameObject.Find("bullet"), transform.position + transform.GetChild(2).transform.right * 2 + -transform.GetChild(2).transform.forward * 0.5f, Quaternion.Euler(0,0,0), transform.parent);
clone.GetComponent<Rigidbody>().constraints = RigidbodyConstraints.None;
transform.GetChild(2).GetChild(0).GetComponent<AudioSource>().Play();
clone.transform.LookAt(clone.transform.position + transform.GetChild(2).transform.right * 5 + -transform.GetChild(2).transform.forward * 0.5f );
clone.GetComponent<Rigidbody>().velocity = transform.GetChild(2).transform.right * 50;
Destroy(clone, 2);
yield return new WaitForSeconds(0.1f);
smoothedweaponspeed = 0.05f;
smoothedrotateweapon = Quaternion.Euler(0,0,0);
smoothedvectorweapon = new Vector3(0.559f,0,-0.523f);
}
}
}
}
i got it, it was a mixture of programming more movement tech for my controller and generally messing around with physics materials and rigidbody mass, also interpolation was pretty important in the process
Related
Here is my code, if it helps anyone...
I don't really know what's wrong with it but when I searched online for an answer nothing helpful came up. It was all player controlled scripts and not anything I could use. Any help would be greatly appreciated, Thanks.
'''
[HideInInspector] public bool moving;
[HideInInspector] public int direction;
public float restTime;
public float speed = 0.1f;
private float maxX = 2f;
private float minX = -2f;
private float currentX;
void Start()
{
SpriteAnimator animator = gameObject.GetComponent<SpriteAnimator>();
currentX = gameObject.transform.position.x;
string message = "Moving: " + moving + ", Dirrection: " + direction + ", Current X: " + currentX;
Debug.Log(message);
}
void Update()
{
if (restTime > 0f)
{
restTime -= Time.deltaTime;
}
else
{
if (direction == 0 && currentX < minX)
{
moving = true;
while (currentX >= minX)
{
currentX = gameObject.transform.position.x;
gameObject.transform.position -= new Vector3(speed * Time.deltaTime, 0f, 0f);
}
moving = false;
restTime = 5f;
}
else
{
moving = true;
while (currentX <= maxX)
{
currentX = gameObject.transform.position.x;
gameObject.transform.position += new Vector3(speed * Time.deltaTime, 0f, 0f);
}
moving = false;
restTime = 5f;
}
}
}
'''
At first glance I see that if (direction == 0 && currentX < minX) should instead be if (direction == 0 && currentX > minX). Another problem that I see is that each frame would see the object be on one side or the other with no frames at positions between the two locations. If this is intended to always run with the object nearly constantly moving back and forth across the screen I would suggest trying this.
IEnumerator MoveObject() {
while(true) {
if(direction == 0) {
while(currentX >= minX) {
gameObject.transform.position -= new Vector3(speed * Time.deltaTime, 0f, 0f);
currentX = gameObject.transform.position.x;
yield return null; // waits for the next frame before continuing
}
direction == 1;
} else {
while(currentX <= maxX) {
gameObject.transform.position += new Vector3(speed * Time.deltaTime, 0f, 0f);
currentX = gameObject.transform.position.x;
yield return null; // waits for the next frame before continuing
}
direction == 0;
}
yield return new WaitForSecondsRealtime(5f); // how long to wait before continuing
// If you want to allow for the "pausing" of the coroutine by modifying the passage of in-game time, you would call
// yield return new WaitForSeconds(5f);
}
}
And you can call it from the Start Method as follows
private void Start() {
// Other Code Here //
_= StartCoroutine(MoveObject());
}
I'm currently getting an issue when my player sprite falls off the land. When I press the 'right arrow' to move horizontally, the sprite suddenly accelerates downwards really fast. I think it is something with the left and right movement but I am unsure if it is the culprit and what the better solution is.
The main portion that I think is causing this issue is this line:
controller.velocity = controller.velocity + new Vector2(horizontal * speed, controller.velocity.y);
I copied this code from a unity forum and at the time it made sense but I believe it is a culprit. If it is, please could you educate on the better solution.
Please let me know if I should include anything else!
Project settings
The y gravity for the project is set to '-9.81'
Player Sprite Object (picture 1)
(picture 2)
Player class (attached to player sprite)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player_script : MonoBehaviour
{
Animator animator = null;
Rigidbody2D controller = null;
SpriteRenderer sprite_renderer = null;
bool walking = false;
bool jumping = false;
int speed = 2;
int jumpSpeed = 200;
const int RIGHT = 1;
const int LEFT = 0;
int direction = RIGHT;
// Start is called before the first frame update
void Start()
{
animator = gameObject.GetComponent<Animator>();
controller = gameObject.GetComponent<Rigidbody2D>();
sprite_renderer = gameObject.GetComponent<SpriteRenderer>();
controller.velocity = Vector3.down * speed;
//Physics.gravity = new Vector3(0, -11.0f, 0);
//controller.AddForce(Vector3.down * 2);
}
// Update is called once per frame
void Update()
{
animate();
//fall
//controller.AddForce(Physics.gravity + (new Vector3(0,-150) * 3), ForceMode2D.Force);
}
void FixedUpdate()
{
//controller.AddForce(Physics.gravity + (new Vector3(0, -150) * 3), ForceMode2D.Force);
//controller.AddForce(Vector3.down * 2);
float horizontal = Input.GetAxis("Horizontal");
float veritical = Input.GetAxis("Vertical");
if (horizontal > 0f)
{
controller.velocity = controller.velocity + new Vector2(horizontal * speed, controller.velocity.y);
walking = true;
if (direction != RIGHT)
{
flipPlayer();
}
}
else if (horizontal < 0f)
{
controller.velocity = controller.velocity + new Vector2((horizontal * speed), controller.velocity.y);
walking = true;
if (direction != LEFT)
{
flipPlayer();
}
}
else
{
walking = false;
}
//jump
if (isGrounded() && veritical > 0f)
{
controller.velocity = controller.velocity + new Vector2(0, veritical * jumpSpeed);
walking = false;
jumping = true;
Debug.Log("Jumping");
}
else
{
jumping = false;
Debug.Log("Not Jumping");
}
}
void animate()
{
if (walking)
{
animator.Play("player_animation");
}
else
{
animator.Play("Idle");
}
}
void flipPlayer() {
if(direction == RIGHT)
{
direction = LEFT;
sprite_renderer.flipX = true;
}
else
{
direction = RIGHT;
sprite_renderer.flipX = false;
}
}
void Jump() { }
bool isGrounded()
{
float raycastDistance = 0.5f;
RaycastHit2D hit = Physics2D.Raycast(transform.position, -Vector2.up, raycastDistance);
if (hit.collider != null && hit.transform.gameObject.layer == LayerMask.NameToLayer("landscapes")) {
return true;
}
return false;
}
}
So the problem you are experiencing is in fact due to the line you were quoting
controller.velocity = controller.velocity + new Vector2(horizontal * speed, controller.velocity.y);
In the Y direction, you are adding the controllers velocity to itself and therefore its Y velocity becomes exponential.
If you wish to override your characters velocity, you should use
controller.velocity = new Vector2(horizontal * speed, controller.velocity.y);
If you wish to add a force to your current velocity, you could do so through code with
controller.velocity = controller.velocity + new Vector2(horizontal * speed * Time.deltaTime, 0);
or by using Rigibody.AddForce(Vector3) with
controller.AddForce(new Vector2(horizontal*speed,0));
I'm trying to make a method that lets players climb a ledge. I have two raycast one for Ledge and one for Wall detection. I the ledge is false, then climb the ledge.
Here comes the problem:
When the Wall check is true and the ledge Check is true, Set player transform.position to be near the ledge. Then afterward transform.position to be above the ledge. But for some reason whenever I try to call Set player transform.position near the ledge, it just teleports back to the default vector value 0, 0.
[Header("Ledge check")]
private bool canClimbLedge = false;
private bool ledgeDetected;
private Vector2 workspace;
//NEW SHIT
private Vector2 detectedPos;
private Vector2 cornerPos;
private Vector2 startPos;
private Vector2 stopPos;
[Header("Ledge Climb State")]
public Vector2 startOffset;
public Vector2 stopOffset;
private void FixedUpdate()
{ if (coll.isTouchingWall && !coll.isTouchingRightLedge || !coll.isTouchingLeftLedge)
{
SetDetectedPosition(transform.position);
}
}
void Update()
{
DetermineCornerPosition();
if (coll.onWall && !coll.isTouchingRightLedge)
CheckLedgeClimb();
if(canClimbLedge && coll.onGround)
FinishLedgeClimb();
if (dir.x < 0)
{
if (groundTouch == true && !wallGrab)
// dustParticle.Play();
if (wallGrab != true)
{
side = -1;
//anim.Flip(side);
}
}
if (dir.x > 0)
{
if (groundTouch == true && !wallGrab)
// dustParticle.Play();
if (wallGrab != true)
{
side = 1;
// anim.Flip(side);
}
}
}
public void SetDetectedPosition(Vector2 pos) => detectedPos = pos;
public Vector2 DetermineCornerPosition()
{
RaycastHit2D xHit = Physics2D.Raycast(coll.wallCheck.position, Vector2.right * side, coll.wallCheckDistance, coll.groundLayer);
float xDist = xHit.distance;
workspace.Set((xDist * side) * side, 0.015f);
RaycastHit2D yHit = Physics2D.Raycast(coll.ledgeCheck.position + (Vector3)(workspace), Vector2.down, coll.ledgeCheck.position.y - coll.wallCheck.position.y + 0.015f, coll.groundLayer);
float yDist = yHit.distance;
//Upper Corner Position of ledge
workspace.Set(coll.wallCheck.position.x + (xDist * side), coll.ledgeCheck.position.y - yDist);
return workspace;
}
private void CheckLedgeClimb()
{
if (coll.isTouchingWall && !coll.isTouchingRightLedge && !ledgeDetected)
{
ledgeDetected = true;
//Freeze player in the detectedPos
rb.velocity = Vector2.zero;
rb.gravityScale = 0f;
transform.position = detectedPos;
cornerPos = DetermineCornerPosition();
}
if(ledgeDetected && !canClimbLedge)
{
canClimbLedge = true;
startPos.Set(cornerPos.x - (side * startOffset.x), cornerPos.y - startOffset.y);
stopPos.Set(cornerPos.x + (side * stopOffset.x), cornerPos.y + stopOffset.y);
}
Debug.Log(startPos);
canMove = false;
transform.position = startPos;
canClimbLedge = true;
}
public void FinishLedgeClimb()
{
//Call the last part of climbing the ledge
}
In the Collision Script:
void FixedUpdate()
{
isTouchingWall = Physics2D.Raycast(wallCheck.position, transform.right, wallCheckDistance, groundLayer);
isTouchingRightLedge = isTouchingWall = Physics2D.Raycast(ledgeCheck.position, transform.right, wallCheckDistance, groundLayer);
}
Any help will be much appreciated, and if you have any other solution to make a ledge climber, I'm all ears.
I reevaluated the purpose was with the script.
The problem was Raycast was not really working correctly
And instead of making the raycast shoot in one direction, I made it follow change 180 degrees if the player was facing left.
And in my game, I didn't want the player to be able to hang from a ledge so the transform.position was removed.
Changes:
Collision Script:
isTouchingWall = Physics2D.Raycast(wallCheck.position, transform.right * move.side, wallCheckDistance, groundLayer);
isTouchingLedge = Physics2D.Raycast(ledgeCheck.position, transform.right * move.side, wallCheckDistance, groundLayer);
ClimbLedge Function:
private void CheckLedgeClimb()
{
if (coll.isTouchingWall && !coll.isTouchingLedge && !ledgeDetected)
{
//Reference point to startPos and stopPos
ledgeDetected = true;
//Freeze player in the detectedPos
rb.velocity = Vector2.zero;
rb.gravityScale = 0f;
transform.position = detectedPos;
cornerPos = DetermineCornerPosition();
Debug.Log("cornerPos Vector Value: " + cornerPos);
canClimbLedge = false;
}
if(ledgeDetected && !canClimbLedge)
{
//This part is only necessary if you want the player to hang from a ledge.
/*startPos.Set(cornerPos.x - (side * startOffset.x), cornerPos.y - startOffset.y);
stopPos.Set(cornerPos.x + (side * stopOffset.x), cornerPos.y + stopOffset.y);
Debug.Log("startPos when ledgeDetected + !canClimbLedge:" + startPos);
canMove = false;
transform.position = startPos;
rb.velocity = Vector2.zero;
rb.gravityScale = 0f;*/
stopPos.Set(cornerPos.x + (side * stopOffset.x), cornerPos.y + stopOffset.y);
rb.velocity = Vector2.zero;
rb.gravityScale = 0f;
canMove = false;
canClimbLedge = true;
}
}
public void FinishLedgeClimb()
{
if (canClimbLedge)
{
transform.position = stopPos;
canClimbLedge = false;
canMove = true;
ledgeDetected = false;
Debug.Log("transform.position = stopPos");
//anim.SetBool("canClimbLedge", canClimbLedge);
}
}
This is working, but the timing of when the player transform.position to the stopPos, is sometimes delayed.
I am working on a Pong-Clone for Android right now and have watched a tutorial about it. It works perfectly with the keyboard, but how do I get a similar control on the mobile phone. My current code looks like this:
private void Start()
{
ball = GameObject.FindGameObjectWithTag("Ball").GetComponent<Ball>();
col = GetComponent<BoxCollider2D>();
if (side == Side.Left)
forwardDirection = Vector2.right;
else if (side == Side.Right)
forwardDirection = Vector2.left;
}
private void Update()
{
if (!overridePosition)
MovePaddle();
}
private void MovePaddle()
{
float targetYPosition = GetNewYPosition();
ClampPosition(ref targetYPosition);
transform.position = new Vector3(transform.position.x, targetYPosition, transform.position.z);
}
private void ClampPosition(ref float yPosition)
{
float minY = Camera.main.ScreenToWorldPoint(new Vector3(0, 0)).y;
float maxY = Camera.main.ScreenToWorldPoint(new Vector3(0, Screen.height)).y;
yPosition = Mathf.Clamp(yPosition, minY, maxY);
}
private float GetNewYPosition()
{
float result = transform.position.y;
if (isAI)
{
if (BallIncoming())
{
if (firstIncoming)
{
firstIncoming = false;
randomYOffset = GetRandomOffset();
}
result = Mathf.MoveTowards(transform.position.y, ball.transform.position.y + randomYOffset, moveSpeed * Time.deltaTime);
}
else
{
firstIncoming = true;
}
}
else
{
float movement = Input.GetAxisRaw("Vertical " + side.ToString()) * moveSpeed * Time.deltaTime;
result = transform.position.y + movement;
}
return result;
}
I want the player to move on the y Axis, but I have no idea how I can do it with touch controls (I am new to games). I would really appreciate any help, so I can continue programming :)
I'm going to assume what you want isove the padel by touch and drag up or down.
I would keep your code for debugging and add a switch to only use touch if touch is supported and your code otherwise.
// Adjust via the Inspector how much the user has to drag in order to move the padel
[SerializeField] private float touchDragSensitivity = 1;
private float lastTouchPosY;
// Make sure to store the camera
// Using Camera.main is quite expensive!
[SerializeField] private Camera _mainCamera;
private void Awake()
{
if(!_mainCamera) _mainCamera = GetComponent<Camera>();
...
}
private float GetNewPosition()
{
...
else
{
var movement = 0f;
if(!Input.touchSupported)
{
// For non-touch device keep your current code
movement = Input.GetAxisRaw("Vertical " + side.ToString()) * moveSpeed * Time.deltaTime;
}
else
{
if(Input.touchCount > 0)
{
var touch = Input.GetTouch(0);
var touchPositionY = _mainCamera.ScreenToWorldPoint(touch.position).y;
if(touch.phase = TouchPhase.Moved)
{
var delta = touchPositionY - lastTouchPosY;
movement = delta * touchDragSensitivity;
}
lastTouchPosY = touchPositionY;
}
}
result = transform.position.y + movement;
}
}
Or alternatively if you rather wanted a similar experience as for the button input you could also only check whether the touch is on the bottom or top half of the screen and move the padel constantly like with your original code before:
private void Update()
{
...
else
{
var movement = 0f;
if(!Input.touchSupported)
{
// For non-touch device keep your current code
movement = Input.GetAxisRaw("Vertical " + side.ToString()) * moveSpeed * Time.deltaTime;
}
else
{
if(Input.touchCount > 0)
{
var touch = Input.GetTouch(0);
var touchPositionY = touch.position.y;
movement = (touchPositionY >= Screen.height / 2f ? 1 : -1) * moveSpeed * Time.deltaTime;
}
}
result = transform.position.y + movement;
}
}
Update
As to your question
is there some way to split the screen so two players can play on the same screen
Yes: You can add a check on which side a touch is using touch.position.x >= screen.width / 2f => right side.
You could e.g. filter for valid touches like
if(Input.touchCount > 0)
{
if(side == Side.Right)
{
var validTouches = Input.touches.Where(t => t.position >= Screen.width / 2f).ToArray();
if(validTouches.Length > 0)
{
var touchPositionY = validTouches[0].position.y;
movement = (touchPositionY >= Screen.height / 2f ? 1 : -1) * moveSpeed * Time.deltaTime;
}
}
else
{
var validTouches = Input.touches.Where(t => t.position < Screen.width / 2f).ToArray();
if(validTouches.Length > 0)
{
var touchPositionY = validTouches[0].position.y;
movement = (touchPositionY >= Screen.height / 2f ? 1 : -1) * moveSpeed * Time.deltaTime;
}
}
}
If you want to press and hold make the object move you can make two buttons one for +y and the other for -y. then use Input.GetTouch to register the players input.
I have this problem which I have been trying to figure out for quite some time already. The code I have below is almost complete. I just need to add this additional feature it should work how I want it to work.
So what I want to implement into the code is the make alertedLock false when !withinRange.
But for some reason no matter how i do it. It doesnt work. Because the problem i have is that, when i implement some kind of code to do that, everything goes back to normal.
Thanks in advance.
Edit
The script should be doing this:
If player !withinRange && !withinAngle of enemy then, enemy.color.blue;
If player !withinRange && withinAngle of enemy then, enemy.color.blue;
If player withinRange && !withinAngle of enemy then, enemy.color.red;
If player withinRange && withinAngle of enemy then, enemy.color.green;
If player withinRange && touchRestrictedRaycast of enemy then, enemy.color.magenta (forever) unless !withinRange && !withinAnge
The problem is 5. I dont know how to code 5.
Edit
When i tried to code it outside the forloop , that is,
if (alertedLock && !withinRange) {
alertedLock = false;
}
Does doesnt solve the problem. It returns the solution to where alertedLock is always false
Even when i try to apply it inside the for loop. Such like,
if(withinRange) {
// Inside
if(alertedLock) {
gameObject.renderer.material.color = Color.magenta;
}
if(!alertedLock) {
if(enemyAngleTLUP || enemyAngleTLLEFT) {
alertedLock = true;
}
if(withinAngle) {
gameObject.renderer.material.color = Color.green;
}
if(!withinAngle) {
gameObject.renderer.material.color = Color.red;
}
}
}
if (!withinRange){
if(alteredLock) {
alertedLock = false;
}
}
There is a problem when i do this, its because once it detects the first raycast detection. It ignores the rest, and so it has this color state problem.
I found out this problem on my earlier questions, here:
https://gamedev.stackexchange.com/questions/90329/raycast-flashing-problem
Edit
alertedLock is just a bool which determines when the player has touched the restricted raycast. Due to the fact the player can only kill the enemy from a certain range and angle (withinRange && withinAngle). This is why we have alertedLock.
However, when alertedLock is true. It can only be turned off when the player isnt within the kill range of the enemy (!withinRange)
using UnityEngine;
using System.Collections;
public class Script_v2 : MonoBehaviour {
// Player Properties
private GameObject player;
public Vector3 playerSize;
private Vector3 playerTransform;
public Vector3 playerTransformTL;
public Vector3 playerTransformTR;
public Vector3 playerTransformBL;
public Vector3 playerTransformBR;
private Vector3 newPlayerTransformTL;
private Vector3 newPlayerTransformTR;
private Vector3[] playerRaycastPoints;
// Enemy Properties
private Vector3 enemyTransformTL;
private Vector3 enemyTransformTR;
private Vector3 enemyTransformBL;
private Vector3 enemyTransformBR;
public float distance;
public Vector3 enemySize;
// Detection Alerts
public bool outOfVision;
public bool alerted;
public bool alertedLock;
public bool withinRange;
public bool withinAngle;
public bool dead;
Ray ray;
RaycastHit hit;
// Use this for initialization
void Start () {
playerRaycastPoints = new Vector3[4];
distance = 3f;
player = GameObject.FindGameObjectWithTag ("Player");
}
// Update is called once per frame
void Update () {
enemyTransformTL = new Vector3 (transform.position.x - 0.5f, transform.position.y + 0.5f, transform.position.z);
enemyTransformTR = new Vector3 (transform.position.x + 0.5f, transform.position.y + 0.5f, transform.position.z);
enemyTransform_TL_TR ();
Reference_Player_Transform_Points ();
Player_Transform_Points_Detection ();
Debug.Log (alerted + " " + alertedLock);
}
void OnDrawGizmos() {
Gizmos.color = Color.blue;
Gizmos.DrawWireSphere (new Vector3(transform.position.x - 0.5f, transform.position.y + 0.5f, transform.position.z), distance);
//Gizmos.DrawWireSphere (new Vector3(transform.position.x + 0.5f, transform.position.y + 0.5f, transform.position.z), distance);
}
public void enemyTransform_TL_TR() {
if (alertedLock && !withinRange) {
alertedLock = false;
}
if (!alertedLock) {
gameObject.renderer.material.color = Color.blue;
}
for (int i = 0; i < playerRaycastPoints.Length; i++) {
double enemyAngleTL = Mathf.Atan2(playerRaycastPoints[i].y - ( transform.position.y + 0.5f ),
playerRaycastPoints[i].x - ( transform.position.x - 0.5f )) * 180f / 3.14159265f;
//Debug.Log (enemyAngleTL);
double enemyAngleTR = Mathf.Atan2 (playerRaycastPoints[i].y - (transform.position.y + 0.5f),
playerRaycastPoints[i].x - (transform.position.x + 0.5f)) * 180f / 3.14159265f;
Vector3 directionTL = (playerRaycastPoints[i] - enemyTransformTL).normalized;
Ray rayTL = new Ray(enemyTransformTL, directionTL);
RaycastHit hitTL;
Vector3 directionTR = (playerRaycastPoints[i] - enemyTransformTR).normalized;
Ray rayTR = new Ray (enemyTransformTR, directionTR);
RaycastHit hitTR;
withinRange = Physics.Raycast (rayTL, out hitTL, distance);
withinAngle = enemyAngleTL > 90 && enemyAngleTL < 180;
RaycastHit hitTPUP;
RaycastHit hitTPLEFT;
bool enemyAngleTLUP = Physics.Raycast(enemyTransformTL, Vector3.up, out hitTPUP, distance);
bool enemyAngleTLLEFT = Physics.Raycast(enemyTransformTL, Vector3.left, out hitTPLEFT, distance);
Debug.DrawRay(enemyTransformTL, Vector3.up * distance);
Debug.DrawRay(enemyTransformTL, Vector3.left * distance);
if(withinRange) {
// Inside
if(alertedLock) {
gameObject.renderer.material.color = Color.magenta;
}
if(!alertedLock) {
if(enemyAngleTLUP || enemyAngleTLLEFT) {
alertedLock = true;
}
if(withinAngle) {
gameObject.renderer.material.color = Color.green;
}
if(!withinAngle) {
gameObject.renderer.material.color = Color.red;
}
}
}
}
}
private void Reference_Player_Transform_Points() {
playerSize = player.transform.localScale;
playerTransformTL = new Vector3(player.transform.position.x - (playerSize.x / 2),
player.transform.position.y + playerSize.y / 2,
player.transform.position.z);
playerTransformTR = new Vector3(player.transform.position.x + (playerSize.x / 2),
player.transform.position.y + playerSize.y / 2,
player.transform.position.z);
playerTransformBL = new Vector3(player.transform.position.x - (playerSize.x / 2),
player.transform.position.y - playerSize.y / 2,
player.transform.position.z);
playerTransformBR = new Vector3(player.transform.position.x + (playerSize.x / 2),
player.transform.position.y - playerSize.y / 2,
player.transform.position.z);
playerRaycastPoints [0] = playerTransformTL;
playerRaycastPoints [1] = playerTransformTR;
playerRaycastPoints [2] = playerTransformBL;
playerRaycastPoints [3] = playerTransformBR;
/*
Debug.Log (playerTransformTL);
Debug.Log (playerTransformTR);
Debug.Log (playerTransformBL);
Debug.Log (playerTransformBR);
*/
}
private void Player_Transform_Points_Detection() {
float eTLpTL = Vector3.Distance (enemyTransformTL, playerTransformTL);
float eTLpTR = Vector3.Distance (enemyTransformTL, playerTransformTR);
float eTLpBL = Vector3.Distance (enemyTransformTL, playerTransformBL);
float eTLpBR = Vector3.Distance (enemyTransformTL, playerTransformBR);
float eTRpTL = Vector3.Distance (enemyTransformTR, playerTransformTL);
float eTRpTR = Vector3.Distance (enemyTransformTR, playerTransformTR);
float eTRpBL = Vector3.Distance (enemyTransformTR, playerTransformBL);
float eTRpBR = Vector3.Distance (enemyTransformTR, playerTransformBR);
float eTLMin = Mathf.Min (eTLpTL, eTLpTR, eTLpBL, eTLpBR);
if (eTLMin == eTLpTL) {
newPlayerTransformTL = playerTransformTL;
// Debug.Log("eTLpTL");
}
else if(eTLMin == eTLpTR) {
newPlayerTransformTL = playerTransformTR;
// Debug.Log("eTLpTR");
}
else if(eTLMin == eTLpBL) {
newPlayerTransformTL = playerTransformBL;
// Debug.Log("eTLpBL");
}
else if(eTLMin == eTLpBR) {
newPlayerTransformTL = playerTransformBR;
// Debug.Log("eTLpBR");
}
float eTRMin = Mathf.Min (eTRpTL, eTRpTR, eTRpBL, eTRpBR);
if(eTRMin == eTRpTL) {
newPlayerTransformTR = playerTransformTL;
// Debug.Log("eTRpTL");
}
else if(eTRMin == eTRpTR) {
newPlayerTransformTR = playerTransformTR;
// Debug.Log("eTRpTR");
}
else if(eTRMin == eTRpBL) {
newPlayerTransformTR = playerTransformBL;
// Debug.Log("eTRpBL");
}
else if(eTRMin == eTRpBR) {
newPlayerTransformTR = playerTransformBR;
// Debug.Log("eTRpBR");
}
}
}