Vector2 bouncing off ScreenHitbox and other CircleHitbox - flutter

This question could be asked to any math wizard, but I am playing around in flame( loads of fun ), so I allow myself to ask it here.
My math is rusty but I have tried using reflect and normalized, but I am way off here. Can you help, and maybe give a direction for both ScreenHitbox & CircleHitbox?
I have CircleHitbox and a collision:
#override
void onCollisionStart(
Set<Vector2> intersectionPoints,
PositionComponent other,
) {
super.onCollisionStart(intersectionPoints, other);
if (other is ScreenHitbox) {
// velocity.reflect(other.position.normalized());
// velocity.reflect(other.size.normalized());
velocity.reflect(intersectionPoints.first.normalized());
// return;
}
}
Update: looking for normal on the collision?

Related

How to render DistanceJoint

I need to render a DistanceJoint, just a line connecting the 2 anchors, nothing fancy. I've seen something about a render method here but I coulen't figure out how to use it. I also don't mind using debug features. Thank you very much :)
Since you have tagged the question with Flame I'm guessing that you are using flame_forge2d?
The link that you provide is for pure forge2d web, but you should be able to do it in a similar fashion in flame_forge2d.
I would try something like this in your Forge2DGame:
final _bodyARenderPosition = Vector2.zero();
final _bodyBRenderPosition = Vector2.zero();
#override
void render(Canvas c) {
super.render(c);
c.save();
c.scale(camera.zoom);
for (final joint in world.joints) {
_bodyARenderPosition
..setFrom(joint.bodyA.position)
..y *= -1;
_bodyBRenderPosition
..setFrom(joint.bodyB.position)
..y *= -1;
c.drawLine(
_bodyARenderPosition.toOffset(),
_bodyBRenderPosition.toOffset(),
debugPaint,
);
}
c.restore();
}

2D raycasting in unity doesn't work

So here is the code I've been working on:
using System.Collections.Generic;
using UnityEngine;
public class MovePlayer : MonoBehaviour
{
public float sidewaysForce;
public float jumpingForce;
public Rigidbody2D playerRigidbody;
public Transform playerTransform;
private Vector2 forceToAdd;
private bool onGround;
private LayerMask mask = 8;
private void Start()
{
forceToAdd = new Vector2(0, 0);
}
void FixedUpdate()
{
// Basic left/right movement
forceToAdd.x = 0;
forceToAdd.y = 0;
if (Input.GetKey(KeyCode.A))
{
forceToAdd.x = -sidewaysForce;
}
else if (Input.GetKey(KeyCode.D))
{
forceToAdd.x = sidewaysForce;
}
if (Input.GetKey(KeyCode.Space) && onGround == true)
{
forceToAdd.y = jumpingForce;
onGround = false;
}
var something = Physics2D.Raycast(playerTransform.position, Vector2.down, 200000f, mask.value);
Debug.Log(something.collider);
playerRigidbody.AddForce(forceToAdd, ForceMode2D.Impulse);
}
}
And my issue is this: No matter how far I move the player upwards, whether it be to (0,5) or (0, 2044), it will still print out "Hit ground."
I've tried both Physics and Physics2D, I've tried LayerMasking, everything, and yet it won't work. I'm a beginner to Unity btw.
EDIT: I printed Physics2D.Raycast(playerTransform.position, Vector3.down, 2f).colliderand I ended up with "Player," not "Ground," any way to fix this? I tried increasing the distance to 20 and to 2000, but it yields "Player," still. Any ideas?
EDIT #2: I also tried LayerMasks, didn't work still.
The issue is that you are parsing Physics2D.Raycast the wrong parameters. As you can see in the Unity docs, the function takes a Vector2 and not a Vector3.
https://docs.unity3d.com/ScriptReference/Physics2D.Raycast.html
Also for testing Raycasts in Unity, always set the distance parameter to be Mathf.Infinity until you have designed the solution completely. This will save you a headache in debugging. It is also best practice to add a comment explaining that it is a temporary distance value and that it should be changed later.
When posting your questions in the future on forums, ensure that you properly explain your questions as I really had to look through your code to find what the purpose was.
I am going to refrain from commenting about your code design as this is stack overflow and not reddit but I teach programming at university and would love to help if you are open to leaning :)

How can I make a variable (preferably boolean) that can determine whether or not a function is running?

CONTEXT
I'm making a unity game and I need to test if my player is on the ground or not, for any of you familiar with things like "OnCollisionEnter", they won't work with the way make game functions, however, "OnControllerColliderHit" works, but there is no negative/exit for this.
What I want to do is have a boolean equal true while the function is running, and once the function has stopped being called (the player is not on the ground), this boolean would turn false.
Feel free to ask if you need any additional information, or (if you are knowledgeable in unity) find a different solution regarding "OnCollisionEnter".
Thanks!
if your problem is checking if the character is on the ground you can make a raycast from your character down to the ground and we add a margin for uneven
platforms you should change this value and find the one that best suits your
ground
float distanceToGround;
float margin;
void Start(){
// get the distance to ground
distanceToGround = collider.bounds.extents.y;
}
boolean IsGrounded() {
return Physics.Raycast(transform.position, -Vector3.up, distanceToGround + margin);
}
void Update () {
if (IsGrounded()){
//DoSomething
}
}
also if your character got a character controller component attached(as you are using OnControllerColliderHit so it is definitely attached ) you can simply check grounded like this
void Start(){
CharacterController controller = GetComponent<CharacterController>();
}
void Update() {
if (controller.isGrounded)
//DoSomething
}

Building/constructing buildings at runtime

I'm playing around with an FPS where I want my player(s) to be able to build/construct their own buildings from scratch. I've searched around for exisiting solutions/theories, but have so far been unable to find anything suitable to my needs. Please point me in the right direction if I've missed anything.
Where I am right now is that I have three prefabs; floor, wall and wall with a door opening. First I want to instantiate floor tiles which I then can put walls on, and hopefully being able to have the walls snap to the edges/corners of the floor tiles.
Can anyone please point me in the right direction for how to do this? Also, does my desired "work flow" at all make sense? Any pitfalls in there?
Thanks in advance!
UPDATE: Here's what I have in regards to instantiation prefabs, and while this works (except it's like I'm shooting walls), I would like the wall to snap to the corners/edges of the nearest floor (which has already been instantiated in the same fashion.
[RequireComponent (typeof (CharacterController))]
public class PlayerController : MonoBehaviour {
// Declare prefabs here
GameObject wallPrefab;
// Initialise variables before the game starts
void Awake () {
wallPrefab = (GameObject)Resources.Load( "WoodWall" );
}
// This happens every frame
void Update () {
if ( Input.GetButtonDown("Fire1") ) {
// Instantiate new wall
Instantiate( wallPrefab, cc.transform.position + cc.transform.forward + Vector3.up * 1.0f, wallPrefab.transform.rotation );
}
}
}
hmm... well one solution I can think of, is to have the wall raycast downwards in order to find a floor, then move to a predetermined position in relation to that floor (if it found any). Stick this in a script in the wall prefabs:
void Start()
{
var down = transform.TransformDirection (Vector3.down); //down might not actually be the down direction of your object, check to make sure
RaycastHit hit;
if (Physics.Raycast(transform.position, down, out hit) && hit.collider.gameObject.name == "myFloorName") //Maybe use tags here instead of name
{
Vector3 floorPos = hit.collider.gameObject.transform.position;
Vector3 floorSize = hit.collider.gameObject.transform.localScale;
this.transform.position = new Vector3(floorPos.x - floorSize.x/2, floorPos.y - this.tranform.localScale.y/2, floorPos.z); //These might need fiddling with to get right
}
}
void Update()
{
}
Vector3.down may not correspond to the down direction for the wall, since this can depend on the 3d model too, so you might need to fiddle with that. The position might also need fiddling with (this assumes that y corresponds to height, which might not be the case), but hopefully this gives you a rough idea of how it can be done. Also, if you don't know what the name of the floor object is, you could probably check by tags, which is probably easier.
If anything else needs clarifying, leave a comment and I'll get back to you

UNITY Lose one life when player hits the water

I want to change the number of lives every time the player hits the water. I wrote this code so far:
public var dieSound:AudioClip;
static var lives = 3;
function Start () {
}
function Update () {
if(lives == 0)
{
Application.LoadLevel("menu");
}
}
public function OnGUI()
{
GUI.backgroundColor = Color.blue;
GUI.Button (Rect (10, 10, 100, 30), "Lives: " + lives);
}
function OnControllerColliderHit (hit : ControllerColliderHit)
{
if (hit.collider.tag == "Water")
{
// play dying sound
audio.PlayOneShot(dieSound);
// show mission fail UI
GameObject.Find("MissionTXT").guiText.enabled = true;
// wait until it's ended
yield WaitForSeconds(dieSound.length + 0.01);
transform.position = GameObject.FindWithTag("Respawn").transform.position;
if (transform.position == GameObject.FindWithTag("Respawn").transform.position)
{
GameObject.Find("MissionTXT").guiText.enabled = false;
lives = lives - 1;
}
}
}
The problem is that when the player hits the water, lives change from 3 to -120. I think that happens because the player is on the water for like 6-7 seconds. So character may hits the water 120 times until he goes back to the original position (Respawn position).
Can anyone help me with that please?
The first thing that comes to mind is as follows:
On your water GameObject, add a Collider component. I would think that a BoxCollider would fit in this scenario. Don't forget to mark the Is Trigger checkbox.
On your player GameObject, add both a RigidBody and a CharacterController (since it looks like you are using the CharacterController component). Make sure to check the RigidBody's Is Kinematic checkbox. Also, give your GameObject a meaningful tag like "Player".
Back to the water GameObject, add a new script that should look something like this:
public class Water : MonoBehaviour {
void OnTriggerEnter(Collider collider) {
if(collider.CompareTag("Player")) {
collider.SendMessage("Kill");
}
}
}
Back to the player GameObject, add a new script that should look something like this:
public class Player : MonoBehaviour {
public void Kill() {
//Perform all necessary steps to kill the player such as...
//Reduce the amount of lives by 1
//Play the death sound
//etc. etc. etc.
}
}
That's the "jist" of things, or this should at least get you started. Unity has some really good documentation and practically anything you need is there, you just have to know where to look. I'm not going to go in-depth of each thing I have mentioned above because as I've said, "Unity has some really good documentation." With that in mind, I highly recommend looking into each of the things I have mentioned. Hope this helps! =)