Own function should run every frame, how is this possible? - c#

I created an own function within a script which should be executed as soon as there is a collision (using OnCollisionEnter).
The idea would be the following:
I have a ring which is steered by the key of the keyboard (Up and Down). Then I produced a sine wave wire with spheres which are moving from right to the left(in a sine wave manner). The player should not be able to move the ring trough the wire.
Therefore I add two colliders to the ring (an Up and a Down collider) and a collision script.
The problem is that sometimes the ring can me moved through the wire... when I press the Up key all the time. Even worse when I do nothing, then the ring should slides along the wire... but it does not.
I think the problem is related to the fact, that my own function is not executed every frame. Or what do you think? How can I execute my own function every frame?
Here the code of the collision script:
void OnCollisionEnter(Collision collUP)
{
if (collUP.gameObject.name == "Sphere(Clone)") {
Debug.Log ("Kollidiert mit UP");
controller.MoveRingDown ();
}
}
And here the code of the ring script in which I created an own function:
public void MoveRingDown() {
transform.position = transform.position + new Vector3 (0f, -tilt, 0f);
}
public void MoveRingUp() {
transform.position = transform.position + new Vector3(0f, tilt, 0f);
}

OnCollisionEnter is only called once, when the collision produces ( as its names reads ). I think what you need is OnCollisionStay, which is executed while the collision lasts.

Related

Unity3d crashes every time I run my game because of the spawner Game object spawning Enemy prefabs

I am about half way done with the firs prototype of my new game-idea, and I am tring to implement a spawner that randomly spawns one of 3 enemy prefabs. This enemy spawning hasn't been working very well for me, as I have always found little problems here and there. One of these problems was major and caused Unity to crash every time I pressed Play ind the editor. I wasn't sure what the problem was, and so I Build the game I tried running the build, and it crashed as well. Then eventually I scraped my spawner and tried a new one. This one also crashed Unity every time, so I tried to spawn a random sphere with no components to it, and this seems to be working perfectly fine.
While running the game In the Unity Editor, I simultaneously open the task manager to see what was going on. It told me Unity was running like a charm, although it used about 1.5 gigs of Ram. Is it a lot? TBH, I don't know if that's the reason it keeps crashing, but I wouldn't know why it takes these amounts of ram. As soon as I deactivated the spawner it stopped crashing, so is it the spawner? I personally don't think so because I was able to spawn the sphere without the game crashing, but as soon as I try to spawn the enemies breaks down.
-> edit: The game doesn't really crash, it just starts loading into infinity, forcing me to end the application and reopen it hands why I am not able to provide any error codes.
Here is the spawner script I used:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Spawner : MonoBehaviour
{
public GameObject[] enemyPrefabs;
public float spawnRate = 1.0f; //The frequency at which enemies spawn.
private float nextSpawn = 0.0f; //used to trigger the next spawn
void Update()
{
//Make enemy spawn on a countdown timer
if (Time.time > nextSpawn)
{
nextSpawn = Time.time + spawnRate; // Trigger next spawn
Debug.Log("Spawn");
//Spawn the enemy in the same place as the spawner
GameObject piClone = Instantiate(enemyPrefabs[Random.Range(0, enemyPrefabs.Length)], transform.position, transform.rotation) as GameObject;
}
}
}

Controlling navmesh agent rotation resulting in odd behavior

I have a navmesh agent, I was not happy with how it updated its rotation (was always slightly off), so I turned it off and did it my self.
It works really nicely, however when I run the game at 3-4 times the speed (management game), they will sometimes lay down flat for 0,5-1 seconds then keep going, I'm assuming it's caused by this script.
Im pretty sure its when they are standing still or just about to turn.
void LateUpdate()
{
if (agent.velocity.sqrMagnitude > Mathf.Epsilon)
{
transform.rotation = Quaternion.LookRotation(agent.velocity.normalized);
}
}
Apparently it was happening while calculating a path, so adding this solved it:
void LateUpdate()
{
if (agent.hasPath)
{
if (agent.velocity.sqrMagnitude > Mathf.Epsilon)
{
transform.rotation = Quaternion.LookRotation(agent.velocity.normalized);
}
}
}

Bullet doesn't move

I'm trying to create a weapon system. Created a new script for weapon. Everything seems to be working fine other than the bullet. It stays in the same place when I press the fire button, doesn't move at all. The bullet is a prefab.
private void Fire()
{
if (Input.GetButtonDown("Fire1"))
{
firingCoroutine = StartCoroutine(FireContinuously());
myAnimator.SetBool("Shoot", true);
}
else if (Input.GetButtonUp("Fire1"))
{
StopCoroutine(firingCoroutine);
myAnimator.SetBool("Shoot", false);
}
}
private void Pistol()
{
GameObject laser = Instantiate(bullet, firePoint.position, firePoint.rotation);
laser.GetComponent<Rigidbody2D>().velocity = new Vector2(projectileSpeed * direction, 0);
}
Sadly I cannot post comments so I'm going to have to post an answer instead, even though I'm more of asking for clarity.
You haven't really shared enough information as to where Pistol() gets executed and if you have even set up the "Fire1" button in "Edit –> Project Settings –> Input", i.e. if those if-statement bodies even get executed. From what I gather though your bullet gets spawned correctly but simply doesn't move?... if so, then you may simply have a case of your bullet Rigidbody2D being marked kinematic or static.

Unity Multiplayer FPS Client/Server Interaction Problems

I have a simple FPS where a player can fire a gun. I want the clients to see the bullet holes. I am trying to accomplish this by invoking a server side method when the client tries to fire the gun. The server side method should then raycast from the players camera and spawn a bullet hole for everyone to see..
I can get this to work partially by passing the player as a parameter to the server method. However, since my raycasting needs to be done based off the player camera, the bullet holes end up appearing at character height, since it's using the player and not the camera.
It won't allow me to pass a camera through. I have also tried creating an empty game object called bullet spawn and passing that through but I was getting a "object reference not set to instance of an object." This same error seems to surface for any Child element of the player I attempt to pass to the server side method.
I am unsure of the right way to accomplish this.
void Update()
{
if (isLocalPlayer)
{
if (Input.GetButton("Fire1"))
{
CmdFire(BulletSpawn);
}
}
}
[Command]
void CmdFire(GameObject Player)
{
Ray shooterRay = new Ray(Player.transform.position, Player.transform.forward);
if (Physics.Raycast(shooterRay, out Hit, 10000))
{
Debug.Log("player hit");
GameObject Bullet_Hole = (GameObject)Instantiate(BulletHole_Prefab, Hit.point, Quaternion.FromToRotation(Vector3.up, Hit.point));
NetworkServer.Spawn(Bullet_Hole);
}
}
Think about it this way. What is it that you need to fire your weapon? You need the firing point and the firing direction (in your simple case). So try to pass just that information. Your CmdFire should look like void CmdFire(Vector3 firingPoint, Vector3 firingDirection). Remember that when you pass the player gameobject, it gets serialized and sent to the server which causes a lot of unneeded network traffic. Stick to value types and simple objects for commands.
This is what ultimately led me to the solution. Thank you for the advice. I simply passed two Vector3 parameters as you suggested which represent the raycast position and direction. I can now shoot from both client and server and see the bullet holes on both as well. Here is the code that fixed it in case anyone runs into this later on:
void Update() {
if (isLocalPlayer) {
if (Input.GetButton("Fire1")) {
Vector3 FiringSpot = PlayerCam.transform.position;
Vector3 FireDirection = PlayerCam.transform.forward;
CmdFire(FiringSpot, FireDirection);
}
}
}
[Command]
void CmdFire(Vector3 firingPoint, Vector3 firingDirection) {
Ray shooterRay = new Ray(firingPoint, firingDirection);
if (Physics.Raycast(shooterRay, out Hit, 10000)) {
GameObject Bullet_Hole = (GameObject)Instantiate(bullet_Hole_Prefab, Hit.point, Quaternion.FromToRotation(Vector3.up, Hit.point));
NetworkServer.Spawn(Bullet_Hole);
Destroy(Bullet_Hole, 10);
}
}

Checking if a navmesh path is blocked takes too long

I'm making a simple tower defence game for mobile. I've written a function to check if placing a tower would prevent the enemies from reaching their goal:
public bool CheckPathNotBlocked(Vector3 pos)
{
navmesh_obstacle_tester.gameObject.SetActive(true);
navmesh_obstacle_tester.position = pos;
NavMeshPath path = new NavMeshPath();
botsInPlay[botsInPlay.Count - 1].CalculatePath(enemyBase.position, path);
navmesh_obstacle_tester.gameObject.SetActive(false);
return path.status == NavMeshPathStatus.PathComplete;
}
The navmesh_obstacle_tester is an empty GameObject with a NavMeshObstacle attached. The botsInPlay is a list of enemy NavMeshAgents so I'm using the most recently spawned enemy to check the path. This actually works but not in time to prevent my tower from being placed:
public void PlaceTower(Vector3 pos, int tType)
{
if (!F_BotsManager.bots.CheckPathNotBlocked(pos)) return;
// rest of my code to place a tower
}
The function exits if the path is completely blocked but does not exit before placing the tower that will block the path e.g. once I've formed a ring of towers around all the enemies no more towers can be placed, but the final tower that completes the ring is placed.
I have read in the docs that path calculation can take a few frames, could this be the cause of the problem? How can I resolve the issue?
You did not show how and where the PlaceTower function is being called. This is really important to figure out how to help.
How can I resolve the issue?
Anything that takes so long to do and you have to wait for it in Unity should be done with a coroutine or a Thread, depending on the thing. In this case, coroutine should be used to wait it so that other things in your code can continue running.
public IEnumerator PlaceTower(Vector3 pos, int tType)
{
while (!F_BotsManager.bots.CheckPathNotBlocked(pos))
{
Debug.Log("waiting!");
yield return null;
}
// rest of my code to place a tower
}
Now, anywhere you called this function should now be replaced with StartCoroutine(PlaceTower(yourPost,yourIntType));. You have to refactor your whole code to accommodate the use of coroutine.

Categories

Resources