- Home /
My char collider didn't get blocked by other box collider
So I have a problem where my character can go through the box collider slightly inside but then get pushed up for some reason, but my bullet can get blocked by the box collider and I have the video to let you guys see the problem.
I want my character to get block/collide by the box as well like the bullet, and I don't see any code in the script that has something to do with the rigidbody of the character
The link: The video is in here
please share how you move your bullet and your player (e.g. forces, setting of a transform. In which function...) . This is most probably the issue here.
Please add code snippets.
Answer by Captain_Pineapple · May 08 at 06:43 AM
Hey,
so by "Code Snippets" i meant the parts of the code that are specifically relevant. Try to not post complete scripts as then the people who are trying to help you have to first find what of the posted stuff even is relevant.
At this point however it is exactly as i expected it:
You move your Projectiles by Physics. So there is a Rigidbody on your projectile which you apply a force on. This way the movement is completly handled by Unitys internal physics engine. This automatically takes care that things do not clip into other objects.
But now you move your player "manually" by directly setting its position:
transform.position = transform.position + (keatas * speed * Time.deltaTime);
This is your issue. When you set the transform manually like this, there will be no check for physics (e.g. collisions) until the next call of FixedUpdate
. So your weird behaviour comes from your player being moved into another object and then unity realizes that there is an overlap and it tries to somehow solve it.
So what to do?
Give your player a kinematic Rigidbody (Kinematic is a little checkbox/dropdown menu on a rigibody) and move it by GetComponent<Rigidbody>().MovePosition()
. Check out this documentation LINK here. Make sure to also check the collision matrices on the bottom of this page here.
If possible do this in FixedUpdate
. Do not do any GetKeyUp
or GetKeyDown` checks in FixedUpdate
- these can be missed as FixedUpdate is not called each Update.
Oh, it actually fix the problem, but then it create the problem where the bullet doesn't blast away and only just standing still.
Nevermind, I found the solution, thank you for the help!
Answer by WiyandiTan64 · May 06 at 10:14 AM
@Captain_Pineapple Code Snippets? I'm sorry, i'm still new to this. so is this right one?
This is the playerControl.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControl : MonoBehaviour
{
public Animator MyAnimator;
public PlayerCombat CombatControl;
Vector3 kekanan;
Vector3 kekiri;
Vector3 keatas;
Vector3 kebawah;
Vector3 hadapDepan;
Vector3 hadapBelakang;
public float speed = 6f;
public bool canMove;
// Start is called before the first frame update
void Start()
{
kekanan = new Vector3(1, 0, 0);
kekiri = new Vector3(-1, 0, 0);
keatas = new Vector3(0, 1, 0);
kebawah = new Vector3(0, -1, 0);
hadapDepan = new Vector3(5, 5, 1);
hadapBelakang = new Vector3(-5, 5, 1);
canMove = true;
CombatControl = GetComponent<PlayerCombat>();
MyAnimator = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
if (Input.GetKey(KeyCode.A) && canMove == true)
{
transform.position = transform.position + (kekiri * speed * Time.deltaTime);
MyAnimator.SetBool(name: "DoWalk", value: true);
transform.localScale = hadapBelakang;
CombatControl.playerDirection = 2;
}
if (Input.GetKeyUp(KeyCode.A))
{
MyAnimator.SetBool(name: "DoWalk", value: false);
}
if (Input.GetKey(KeyCode.S) && canMove == true)
{
transform.position = transform.position + (kebawah * speed * Time.deltaTime);
MyAnimator.SetBool(name: "DoWalk", value: true);
}
if (Input.GetKeyUp(KeyCode.S))
{
MyAnimator.SetBool(name: "DoWalk", value: false);
}
if (Input.GetKey(KeyCode.D) && canMove == true)
{
transform.position = transform.position + (kekanan * speed * Time.deltaTime);
MyAnimator.SetBool(name: "DoWalk", value: true);
transform.localScale = hadapDepan;
CombatControl.playerDirection = 1;
}
if (Input.GetKeyUp(KeyCode.D))
{
MyAnimator.SetBool(name: "DoWalk", value: false);
}
if (Input.GetKey(KeyCode.W) && canMove == true)
{
transform.position = transform.position + (keatas * speed * Time.deltaTime);
MyAnimator.SetBool(name: "DoWalk", value: true);
}
if (Input.GetKeyUp(KeyCode.W))
{
MyAnimator.SetBool(name: "DoWalk", value: false);
}
if (Input.GetKeyUp(KeyCode.Space))
{
}
}
}
This is the playerCombat
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerCombat : MonoBehaviour
{
public int playerDirection = 1;
public Animator MyAnimator;
public Transform attackPoint;
public Transform firePoint;
public GameObject bulletPrefab;
public PlayerControl PlayerMovement;
public float bulletForce = 20f;
private IEnumerator coroutine;
public float attackRangeLight = 0.5f;
Vector3 hadapDepan;
Vector3 hadapBelakang;
public LayerMask enemyLayers;
// ini untuk mendapatkan range musuh layer agar bisa berinteraksi serangannya
public int attackDamageLight = 12;
public float attackRateLight = 2f;
float nextAttackTimeLight = 2f;
public int attackDamageHeavy = 30;
public float attackRateHeavy = 1f;
float nextAttackTimeHeavy = 2f;
// Start is called before the first frame update
void Start()
{
hadapDepan = new Vector3(4, 4, 1);
hadapBelakang = new Vector3(-4, 4, 1);
PlayerMovement = GetComponent<PlayerControl>();
MyAnimator = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
if (Time.time >= nextAttackTimeLight && Time.time >= nextAttackTimeHeavy)
{
if (Input.GetKeyUp(KeyCode.J))
{
PlayerMovement.canMove = false;
LightAttack();
nextAttackTimeLight = Time.time + 1f / attackRateLight;
// untuk timing attack rate
coroutine = WaitDelay(1f);
StartCoroutine(coroutine);
}
if (Input.GetKeyUp(KeyCode.K))
{
PlayerMovement.canMove = false;
Shoot();
nextAttackTimeHeavy = Time.time + 1f / attackRateHeavy;
coroutine = WaitDelay(1f);
StartCoroutine(coroutine);
}
}
}
void LightAttack()
{
MyAnimator.SetTrigger(name: "DoLightAttack");
PlayerMovement.canMove = false;
Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(attackPoint.position, attackRangeLight, enemyLayers);
foreach (Collider2D enemy in hitEnemies)
{
enemy.GetComponent<Enemy>().TakeDamage(attackDamageLight);
}
}
void Shoot()
{
MyAnimator.SetTrigger(name: "DoHeavyAttack");
GameObject bullet = Instantiate(bulletPrefab, firePoint.position, Quaternion.identity);
Rigidbody2D rb = bullet.GetComponent<Rigidbody2D>();
switch (playerDirection)
{
case 1:
bullet.transform.localScale = hadapDepan;
rb.AddForce(firePoint.right * bulletForce, ForceMode2D.Impulse);
break;
case 2:
bullet.transform.localScale = hadapBelakang;
rb.AddForce(-firePoint.right * bulletForce, ForceMode2D.Impulse);
break;
}
// ini untuk menentukan player directionnya, agar nanti saat menembak pelurunya akan menghadap berdasarkan posisi player
Destroy(bullet, 5f);
}
void OnDrawGizmosSelected()
{
if (attackPoint == null)
return;
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(attackPoint.position, attackRangeLight);
}
private IEnumerator WaitDelay(float waitTime)
{
while (true)
{
yield return new WaitForSeconds(waitTime);
PlayerMovement.canMove = true;
}
}
}
This is the bullet script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class bullet : MonoBehaviour
{
public GameObject hitEffect;
void OnCollisionEnter2D(Collision2D coll)
{
GameObject effect = Instantiate(hitEffect, transform.position, Quaternion.identity);
Destroy(effect, 5f);
Destroy(gameObject);
}
void OnTriggerEnter2D(Collider2D coll2)
{
if (coll2.gameObject.tag == "Enemy")
{
coll2.GetComponent<Enemy>().TakeDamage(30);
GameObject effect = Instantiate(hitEffect, transform.position, Quaternion.identity);
Destroy(effect, 5f);
Destroy(gameObject);
}
}
}