Raycasting unknown error - c#

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");
}
}
}

Related

Rotate Object Smoothly

i am trying to rotate object to 90 degrees smoothly on swipe here in my code its rotate instantly, how do i rotate object smoothly at given speed.
void Update()
{
if (fingerDown == false && Input.GetMouseButtonDown(0))
{
startPos = Input.mousePosition;
fingerDown = true;
}
if (fingerDown)
{
if (Input.mousePosition.x >= startPos.x + pixelDistToMove)
{
startPos = Input.mousePosition;
Vector3 rotationToAdd = new Vector3(0, 0, 90);
transform.Rotate(rotationToAdd);
fingerDown = false;
}
if (Input.mousePosition.x <= startPos.x - pixelDistToMove)
{
startPos = Input.mousePosition;
Vector3 rotationToAdd = new Vector3(0, 0, -90);
transform.Rotate(rotationToAdd);
fingerDown = false;
}
}
if (fingerDown && Input.GetMouseButtonUp(0))
{
fingerDown = false;
}
}
Thank you
transform.Rotate() rotates the object without animating it's rotation.
If you want it to rotate smoothly, you have to implement either an animation, or a turning state, or an IEnumerator.
My C# is a bit rusty, but I cooked this up:
public Vector3 desired_angle = Vector3.zero; // Turn the Gameobject to this angle
public float turn_time = 1f; // How long should turning take
public float rate = 60;
private void Update ()
{
if (Input.GetKeyDown(KeyCode.Space))
{
StartCoroutine(TurnTo());
}
}
IEnumerator TurnTo ()
{
Vector3 original_angle = transform.rotation.eulerAngles;
for (float i = 0f; i < 1f + turn_time / rate; i += turn_time / rate)
{
transform.rotation = Quaternion.Euler(Vector3.Lerp(original_angle, desired_angle, i));
yield return new WaitForSeconds(turn_time/rate);
}
}

Getting the right movement down

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

Trying to making a ledge. The problem: transform.position always returns to vector( 0, 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.

Unity2D no bullet trail while shooting at enemy

https://gyazo.com/0a29918f513316fc4143a5ff76095bd3
This is how it looks visually.
That's my shooting weapon code:
public class Weapon : MonoBehaviour {
public float fireRate = 0;
public float maxDamage = 10;
public LayerMask whatToHit ;
public Transform BulletTrailPrefab;
public Transform MuzzleFlashPrefab;
public Transform HitPrefab;
float timeToSpawnEffect = 0;
public float effectSpawnRate = 10;
float timeToFire = 0;
Transform firePoint;
// Use this for initialization
void Awake () {
firePoint = transform.FindChild("FirePoint");
if(firePoint == null)
{
Debug.LogError("No FirePoint");
}
}
// Update is called once per frame
void Update () {
if(fireRate == 0)
{
if (Input.GetButtonDown("Fire1"))
{
Shoot();
}
}else
{
if(Input.GetButton("Fire1") && Time.time > timeToFire)
{
timeToFire = Time.time + 1 / fireRate;
Shoot();
}
}
}
void Shoot()
{
Vector2 mousePosition = new Vector2(Camera.main.ScreenToWorldPoint(Input.mousePosition).x, Camera.main.ScreenToWorldPoint(Input.mousePosition).y);
Vector2 firePointPosition = new Vector2(firePoint.position.x, firePoint.position.y);
RaycastHit2D hit = Physics2D.Raycast(firePointPosition,mousePosition - firePointPosition,100,whatToHit);
Debug.DrawLine(firePointPosition, (mousePosition - firePointPosition) * 100,Color.cyan);
if(hit.collider != null)
{
Debug.DrawLine(firePointPosition, hit.point, Color.red);
Enemy enemy = hit.collider.GetComponent<Enemy>();
if(enemy != null)
{
enemy.DamageEnemy(Random.Range(maxDamage/2,maxDamage));
// Debug.Log("we hit" + hit.collider.name + " and did: " + maxDamage + " damage");
}
}
if (Time.time >= timeToSpawnEffect)
{
Vector3 hitPos;
Vector3 hitNormal;
if (hit.collider == null)
{
hitPos = (mousePosition - firePointPosition) * 30;
hitNormal = new Vector3(9999, 9999, 9999);
}
else
{
hitPos = hit.point;
hitNormal = hit.normal;
}
Effect(hitPos,hitNormal);
timeToSpawnEffect = Time.time + 1 / effectSpawnRate;
}
}
void Effect(Vector3 hitPos, Vector3 hitNormal)
{
Transform trail = Instantiate(BulletTrailPrefab,firePoint.position,firePoint.rotation) as Transform;
LineRenderer lr = trail.GetComponent<LineRenderer>();
if(lr != null)
{
// Set positions
lr.SetPosition(0, firePoint.position);
lr.SetPosition(1, hitPos);
}
Destroy(trail.gameObject, 0.035f);
if (hitNormal != new Vector3(9999, 9999, 9999))
{
Transform hitParticle = Instantiate(HitPrefab, hitPos, Quaternion.FromToRotation(Vector3.right,hitNormal)) as Transform;
hitParticle.parent = transform.parent;
Destroy(hitParticle.gameObject, 0.3f);
}
Transform clone = Instantiate(MuzzleFlashPrefab, firePoint.position, firePoint.rotation);
clone.parent = firePoint;
float size = Random.Range(0.3f, 0.5f);
clone.localScale = new Vector3(size, size, size);
Destroy(clone.gameObject, 0.02f);
}
}
I've been trying to figure it out what's wrong for hours now. Checked the code just too many times, don't know how to google this problem. Just can't understand why it's hitting everything except that spaceship..
Don't know what other information you might need so tell me if you need something more.

2D Character falls off the map in Unity3D

I am currently working on a project for one of the courses i am taking.
I am making a 2D game in unity3D, and i have a small problem, every time i run the game my character keeps on falling through the map, even though i have added a rigidbody2D and a boxCollider2D to both my character and the foreground. The code is attached, it is in C# and it is a bit long. Thank you so much in advance ..
enter code here
using System;
using UnityEngine;
using System.Collections;
public class CharacterController2D : MonoBehaviour
{
private const float SkinWidth = .02f;
private const int TotalHorizontalRays = 8;
private const int TotalVerticalRays = 4;
private static readonly float SlopeLimitTanget = Mathf.Tan (75f * Mathf.Deg2Rad);
public LayerMask PlatformMask;
public ControllerParameters2D DefaultParameters;
public ControllerState2D State { get; private set; }
public Vector2 Velocity { get { return _velocity; }}
public bool HandleCollisions { get; set; }
//Return overrideparamteres if it is not null, if it is null it will return DefaultParameters
public ControllerParameters2D Parameters { get { return _overrideParameters ?? DefaultParameters; } }
public GameObject StandingOn { get; private set;}
public Vector3 PlatformVelocity { get; private set;}
public bool CanJump
{
get
{
if(Parameters.JumpRestrictions == ControllerParameters2D.JumpBehavior.CanJumpAnywhere)
return _jumpIn <= 0;
if(Parameters.JumpRestrictions == ControllerParameters2D.JumpBehavior.CanJumpOnGround)
return State.IsGrounded;
return false;
}
}
private Vector2 _velocity;
private Transform _transform;
private Vector3 _localScale;
private BoxCollider2D _boxCollider;
private ControllerParameters2D _overrideParameters;
private float _jumpIn;
private GameObject _lastStandingOn;
private Vector3
_activeGlobalPlatformPoint,
_activeLocalPlatformPoint;
private Vector3
_raycastTopLeft,
_raycastBottomRight,
_raycastBottomLeft;
private float _verticalDistanceBetweenRays,
_horizonatalDistanceBetweenRays;
public void Awake()
{
HandleCollisions = true;
State = new ControllerState2D();
_transform = transform;
_localScale = transform.localScale;
_boxCollider = GetComponent <BoxCollider2D>();
// Absolute Value
var colliderWidth = _boxCollider.size.x * Mathf.Abs(transform.localScale.x) - (2 * SkinWidth);
_horizonatalDistanceBetweenRays = colliderWidth / (TotalVerticalRays - 1);
var colliderHeight = _boxCollider.size.y * Mathf.Abs( transform.localScale.y ) - (2 * SkinWidth);
_verticalDistanceBetweenRays = colliderHeight / (TotalHorizontalRays - 1);
}
public void AddForce(Vector2 force)
{
_velocity = force;
}
public void SetForce(Vector2 force)
{
_velocity += force;
}
public void SetHorizontalForce(float x)
{
_velocity.x = x;
}
public void SetVerticalForce(float y)
{
_velocity.y = y;
}
public void Jump()
{
AddForce(new Vector2(0, Parameters.JumpMagnitude));
_jumpIn = Parameters.JumpFrequency;
}
public void LateUpdate()
{
_jumpIn -= Time.deltaTime;
//We force the player to go up or down based on the gravity
_velocity.y += Parameters.Gravity * Time.deltaTime;
//Move the characther per his velocity scaled by time
Move (Velocity * Time.deltaTime);
}
// Ensures the player doesn't fall off the map or move through the wall
private void Move(Vector2 deltaMovement)
{
var wasGrounded = State.IsCollidingBelow;
State.Reset();
if(HandleCollisions)
{
HandlePlatforms();
CalculateRayOrigins();
if(deltaMovement.y < 0 && wasGrounded)
HandleVerticalSlope(ref deltaMovement);
if(Mathf.Abs(deltaMovement.x) > .001f)
MoveHorizontally(ref deltaMovement);
MoveVertically(ref deltaMovement);
CorrectHorizontalPlacement(ref deltaMovement, true);
CorrectHorizontalPlacement(ref deltaMovement, false);
}
_transform.Translate(deltaMovement, Space.World);
if (Time.deltaTime > 0)
_velocity = deltaMovement / Time.deltaTime;
_velocity.x = Mathf.Min (_velocity.x, Parameters.MaxVelocity.x);
_velocity.y = Mathf.Min (_velocity.y, Parameters.MaxVelocity.y);
if(State.IsMovingUpSlope)
_velocity.y = 0;
//Standing on the platform
if(StandingOn != null)
{
_activeGlobalPlatformPoint = transform.position;
_activeLocalPlatformPoint = StandingOn.transform.InverseTransformPoint(transform.position);
Debug.DrawLine(transform.position, _activeGlobalPlatformPoint);
Debug.DrawLine(transform.position, _activeLocalPlatformPoint + StandingOn.transform.position);
if(_lastStandingOn != StandingOn)
{
//If the last thing we are standing on is not null, send a message to leave it
if(_lastStandingOn != null)
_lastStandingOn.SendMessage("ControllerExist2D", this, SendMessageOptions.DontRequireReceiver);
//Inform what we are standing on that we have entered
StandingOn.SendMessage("ControllerEnter2D", this, SendMessageOptions.DontRequireReceiver);
_lastStandingOn = StandingOn;
}
//Invoke the platform that we are standing on it
else if (StandingOn != null)
StandingOn.SendMessage("ControllerStay2D", this, SendMessageOptions.DontRequireReceiver);
}
else if (_lastStandingOn != null)
{
_lastStandingOn.SendMessage("ControllerExit2D", this, SendMessageOptions.DontRequireReceiver);
_lastStandingOn = null;
}
}
private void HandlePlatforms()
{
//Calculate the velocity of the platform
if(StandingOn != null)
{
var newGlobalPlatformPoint = StandingOn.transform.TransformPoint(_activeLocalPlatformPoint);
var moveDistance = newGlobalPlatformPoint - _activeGlobalPlatformPoint;
//Sticks the player on the platform, wherever the platform teleport the players stays on it
if(moveDistance != Vector3.zero)
transform.Translate(moveDistance, Space.World);
PlatformVelocity = (newGlobalPlatformPoint - _activeGlobalPlatformPoint) / Time.deltaTime;
}
else
PlatformVelocity = Vector3.zero;
StandingOn = null;
}
private void CorrectHorizontalPlacement(ref Vector2 deltaMovement, bool isRight)
{
var halfwidth = (_boxCollider.size.x * _localScale.x) / 2f;
var rayOrigin = isRight ? _raycastBottomRight : _raycastBottomLeft;
if(isRight)
rayOrigin.x -= (halfwidth - SkinWidth);
else
rayOrigin.x += (halfwidth - SkinWidth);
var rayDirection = isRight ? Vector2.right : -Vector2.right;
var offset = 0f;
for(var i = 1; i <= TotalHorizontalRays - 1; i++)
{
var rayVector = new Vector2(deltaMovement.x + rayOrigin.x, deltaMovement.y + rayOrigin.y + (i * _verticalDistanceBetweenRays));
Debug.DrawRay(rayVector, rayDirection * halfwidth, isRight ? Color.cyan : Color.magenta);
var raycastHit = Physics2D.Raycast(rayVector, rayDirection, halfwidth, PlatformMask);
if(!raycastHit)
continue;
offset = isRight ? ((raycastHit.point.x - _transform.position.x) - halfwidth) : (halfwidth - (_transform.position.x - raycastHit.point.x));
}
deltaMovement.x += offset;
}
private void CalculateRayOrigins()
{
var size = new Vector2 (_boxCollider.size.x * Mathf.Abs (_localScale.x), _boxCollider.size.y * Mathf.Abs (_localScale.y)) / 2;
var center = new Vector2(_boxCollider.center.x * _localScale.x, _boxCollider.center.y * _localScale.y);
//Location of the player, then we add the box collider to it relative to the center of the player
_raycastTopLeft = _transform.position + new Vector3 (center.x - size.x + SkinWidth, center.y + size.y - SkinWidth);
_raycastBottomRight = _transform.position + new Vector3 (center.x + size.x - SkinWidth, center.y - size.y + SkinWidth); //Going right
_raycastBottomLeft = _transform.position + new Vector3 (center.x - size.x + SkinWidth, center.y - size.y + SkinWidth); //Going left and down-up
}
//Cast rays to the left or to the right depending on the player's movement
//Determining how far the player can go either to the left, or to the right
private void MoveHorizontally(ref Vector2 deltaMovement)
{
var isGoingRight = deltaMovement.x > 0;
//The distance between the starting point and the final destination
var rayDistance = Mathf.Abs (deltaMovement.x) + SkinWidth;
//Where is the player going? right or left
var rayDirection = isGoingRight ? Vector2.right : -Vector2.right;
//Right? we start from bottom right. Left? we start fro, bottom left
var rayOrigin = isGoingRight ? _raycastBottomRight : _raycastBottomLeft;
//Determines how many rays we want to shoot out to the left or to the right
for(var i = 0; i < TotalHorizontalRays; i++)
{
var rayVector = new Vector2(rayOrigin.x, rayOrigin.y + (i * _verticalDistanceBetweenRays));
//Visual representation about the rays
Debug.DrawRay(rayVector, rayDirection * rayDistance, Color.red);
//Checks if the player hit something or not
var rayCastHit = Physics2D.Raycast(rayVector, rayOrigin, rayDistance, PlatformMask);
if(!rayCastHit) //If there was a raycast then do something, otherwise continue to loop
continue;
//We return true if we are on a horizotnal slope, and check if we are going right or left or hit something while going up
if(i == 0 && HandleHorizontalSlope(ref deltaMovement, Vector2.Angle(rayCastHit.normal, Vector2.up), isGoingRight))
break;
//If we hit something then we can only go that far forward
deltaMovement.x = rayCastHit.point.x - rayVector.x;
rayDistance = Mathf.Abs(deltaMovement.x);
if(isGoingRight)
{
//If we are going right, then we have to substract the skinwidth
deltaMovement.x -= SkinWidth;
State.IsCollidingRight = true;
}
else
{
//The oppoiste of the if statement, if we are going left, we add the skinwidth
deltaMovement.x += SkinWidth;
State.IsCollidingLeft = true;
}
//Handles error collision, if the player hits something and go through it
if(rayDistance < SkinWidth + .0001f)
break;
}
}
private void MoveVertically(ref Vector2 deltaMovement)
{
//Check to see if going up or down
var isGoingUp = deltaMovement.y > 0;
var rayDistance = Mathf.Abs (deltaMovement.y) + SkinWidth;
var rayDirection = isGoingUp ? Vector2.up : -Vector2.up;
var rayOrigin = isGoingUp ? _raycastTopLeft : _raycastBottomLeft;
rayOrigin.x += deltaMovement.x;
var standingOnDistance = float.MaxValue;
for(var Count = 0; Count < TotalVerticalRays; Count++)
{
var rayVector = new Vector2(rayOrigin.x + (Count * _horizonatalDistanceBetweenRays), rayOrigin.y);
Debug.DrawRay(rayVector, rayDirection * rayDistance, Color.red);
var raycastHit = Physics2D.Raycast(rayVector, rayDirection, rayDistance, PlatformMask);
//If the player hit nothing then keep going.
if(raycastHit)
{
continue;
}
if(!isGoingUp)
{
var verticalDistanceToHit = _transform.position.y - raycastHit.point.y;
if(verticalDistanceToHit < standingOnDistance)
{
standingOnDistance = verticalDistanceToHit;
//Platform we are standing on
StandingOn = raycastHit.collider.gameObject;
}
}
//Determine the furthest distance we can move down or up without hitting anything
deltaMovement.y = raycastHit.point.y - rayVector.y;
rayDistance = Mathf.Abs(deltaMovement.y);
if(isGoingUp)
{
deltaMovement.y -= SkinWidth;
State.IsCollidingAbove = true;
}
else
{
deltaMovement.y += SkinWidth;
State.IsCollidingBelow = true;
}
if(!isGoingUp && deltaMovement.y > .0001f)
{
State.IsMovingUpSlope = true;
}
if(rayDistance < SkinWidth + .0001f)
{
break;
}
}
}
private void HandleVerticalSlope(ref Vector2 deltaMovement)
{
//Give us the center of the vertical rays;
var center = (_raycastBottomLeft.x + _raycastBottomRight.x) / 2;
var direction = -Vector2.up;
var slopeDistance = SlopeLimitTanget * (_raycastBottomRight.x - center);
var slopeRayVector = new Vector2 (center, _raycastBottomLeft.y);
Debug.DrawRay(slopeRayVector, direction * slopeDistance, Color.yellow);
var raycastHit = Physics2D.Raycast (slopeRayVector, direction, slopeDistance, PlatformMask);
if (!raycastHit)
return;
// ReSharper disable CompareOfFloatsByEqualityOperator
var isMovingDownSlope = Mathf.Sign (raycastHit.normal.x) == Mathf.Sign (deltaMovement.x);
if(!isMovingDownSlope)
return;
var angle = Vector2.Angle (raycastHit.normal, Vector2.up);
if(Mathf.Abs(angle) < .0001f)
return; //Which means there we are not on a slope, we are on something else
State.IsMovingDownSlope = true;
State.SlopeAngle = angle;
deltaMovement.y = raycastHit.point.y - slopeRayVector.y;
}
private bool HandleHorizontalSlope(ref Vector2 deltaMovement, float angle, bool isGoingRight)
{
//We do not want to move to an angle of 90
if(Mathf.RoundToInt(angle) == 90)
return false;
if(angle > Parameters.SlopeLimit)
{
deltaMovement.x = 0;
return true;
}
if(deltaMovement.y > .07f)
return true;
deltaMovement.x += isGoingRight ? -SkinWidth : SkinWidth;
deltaMovement.y = Mathf.Abs (Mathf.Tan (angle * Mathf.Deg2Rad) * deltaMovement.x);
State.IsMovingUpSlope = true;
State.IsCollidingBelow = true;
return true;
}
public void OnTriggerEnter2D(Collider2D other)
{
var parameters = other.gameObject.GetComponent<ControllerPhysicsVolume2D>();
if(parameters == null)
return;
_overrideParameters = parameters.Parameters;
}
public void OnTriggerExit2D(Collider2D other)
{
var parameters = other.gameObject.GetComponent<ControllerPhysicsVolume2D>();
if(parameters == null)
return;
_overrideParameters = null;
}
}
As #Terrance said you really don't need to write your own code logic for collision detection.
Secondly I noticed OnTriggerEnter2D and OnTriggerExit2D methods in your code, that also points out to one thing that all your boxCollider2d has isTrigger option checked. Therefore, I suggest you to uncheck isTrigger option on both your player and ground as TRIGGER will never stop two objects from crossing each other (you need to have both objects have 'isTrigger' unchecked on their colliders if you don't want them to pass through each other). And use method OnCollisionEnter2D and OnCollisionExit2D to detect the collision.
What is difference between Trigger and a Collider:
Taking real world example Colliders are tangible object e.g you yourself and the floor you are standing on both are solid and tangible.
While trigger is intangible, example of triggers can be the walkthrough security doors; these doors are hollow from inside allowing any person to pass without any hindrance, but if you wear any metal object on yourself and pass through that "Hollow Area" between the door, the door will TRIGGER an alarm. therefore with respect to the game world you can say that the door has a trigger at it hollow area.

Categories