I ask for code ideas, the reason why I write below - unity3d

Hello everyone. I have a character like the picture below, I want when playing the game, this character collides with another character, this character will be hidden (Exactly hide the entire skin shirt, okay? , but the character still moves normally) after about 10 seconds, it will show the skin again as shown below.
I'm stuck in the code. I tried to enable skinnedmeshrenderer , but it forces the sence to reload and it doesn't work very well. If you have any ideas, please let me know. Thank you!!!!

So for this you need to look up how to use colliders. You might want a simple box collider, or even a mesh collider. Then you need to tag the colliders (Go to Learn.Unity or the YouTube website to look for some guides if you don't know about these).
Then use private void OnCollisionEnter(Collision col){} and check col.tag to see if it's what you want and set the character GameObject to innactive* character.SetActive(false);
Then, set a float timer to 10 timer=10; and in Update run
if (timer > 0)
{
timer -= Time.deltaTime;
if (timer <= 0)
{
character.SetActive(true);
}
}
which will reactivate your character after 10 seconds.
* Note
If you don't want to turn the gameObject off, you can instead save the mesh in a variable then set it to null for 10 seconds before restoring it
Alternate solution:
Script used:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
[SerializeField] SkinnedMeshRenderer skinnedMeshRenderer;
Mesh mesh;
float timer = 0;
// Start is called before the first frame update
void Start()
{
mesh = skinnedMeshRenderer.sharedMesh;
}
// Update is called once per frame
void Update()
{
if (timer > 0)
{
timer -= Time.deltaTime;
if (timer <= 0)
{
skinnedMeshRenderer.sharedMesh = mesh;
}
}
if (Input.GetMouseButtonDown(0))
{
skinnedMeshRenderer.sharedMesh = null;
timer = 10;
}
}
}
Model "Steve" thanks to Penny DeBylle

Related

Why does exporting to Unity WebGL change the speed of objects in my game?

GOAL
So I have a space-invaders type game I have made to practise unity and I want to upload it to Itch.io as I have done in the past.
This is a clip of the game.
I switched platforms to WebGL in Build Settings etc, and everything worked fine in Unity.
PROBLEM
However when I built it and uploaded the zip file to Itch.io, the aliens are now a lot faster than usual. (Be aware there may be other things that have changed, I just haven't been able to get to them since it is extremely hard).
CODE
Alien movement:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class AleenController : MonoBehaviour
{
Rigidbody2D rigidbody;
public float speed = 10f;
ScoreController scoreController;
AudioSource aleenDie;
void Start()
{
scoreController = GameObject.Find("Canvas/Score").GetComponent<ScoreController>();
rigidbody = GetComponent<Rigidbody2D>();
aleenDie = GameObject.Find("Main Camera/AleenDie").GetComponent<AudioSource>();
}
void Update()
{
rigidbody.MovePosition(transform.position + new Vector3 (0, -1, 0) * speed * Time.deltaTime);
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.tag == "laser")
{
aleenDie.Play();
scoreController.score += 1;
Destroy(gameObject);
}
}
}
NOTE
I am really struggling to find out what is wrong here, since everything is fine in unity. If you do need more details just leave a comment.
If you use physics you should
not set or get values via Transform at all
do things in FixedUpdate
In general though in your case instead of using
void Update()
{
rigidbody.MovePosition(transform.position + new Vector3 (0, -1, 0) * speed * Time.deltaTime);
}
at all simply set the velocity once like e.g.
void Start ()
{
...
rigidbody.velocity = Vector3.down * speed;
}
The rest seems to depend a bit on your screen size. Looks like you are moving your elements in pixel space -> the smaller the display the less pixel distance between the top and bottom -> the faster elements seem to travel.

How Do I Destroy Finished Walking Particle (Clones) in UNITY?

VIDEO < in the video I have a walking particles that appear when ever my player moves left and right but I want them to be destroyed after the particles are finished fading away I tried using stop action in unity but that only destroyes the finish particles when the player stops moving and after that the particles will
stop showing up
these are my dublicated particles that will stay in my game forever and cause lag later on I need a way to stop showing them when they are done
IMAGE < the inspector of my particles
image < the name of my particles
is there a way I could some how in my code check if the particle is faded away or check if its finished and then destroy those because sometimes with the destroy it will destroy everything and the particles wont show up if I walk again
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class partscript2 : MonoBehaviour
{
public Joystick joystick2;
public GameObject hays2;
public Rigidbody2D rb;
float horizontalMove = 0f;
// public bool show = true;
public Animator animator3;
// public Transform player;
//public Transform particleposition;
// Start is called before the first frame update
void Start()
{
//transform.position = particleposition.position;
animator3 = GetComponent<Animator>();
//Destroy(gameObject, 1f);
}
//destroy(hays);
// Update is called once per frame
void Update()
{
if (joystick2.Horizontal <= -.2f)
{
Instantiate(hays2, transform.position, hays2.transform.rotation);
}
if (joystick2.Horizontal >= .2f)
{
Instantiate(hays2, transform.position, hays2.transform.rotation);
}
}
}
Firstly, instantiating a game object in update is not the best way to go considering that if your game runs at 60 frames per second you will end up creating 60 game objects each second which can and most likely will affect performance especially on a mobile device which you are working.
But into the point, you can call the Destroy method and pass the duration of the particle.
GameObject hay = Instantiate(hays2, transform.position, hays2.transform.rotation);
ParticleSystem p = hay.GetComponent<ParticleSystem>();
float duration = p.duration + p.startLifetime;
Destroy(hay , duration);
If your particle's duration is fixed you can always skip the part where we get the duration via script and simply pass it in the Destroy method.
GameObject hay = Instantiate(hays2, transform.position, hays2.transform.rotation);
Destroy(hay , 5f);

Unity Multiplayer: Reset player position when Y axis is less then -2

i'm having this issue with resetting the players position when the players Y axis is less then the threshold value which is -2.
using UnityEngine;
using UnityEngine.Networking;
public class ResetPlayerPosition : NetworkManager {
public float threshold = -2f;
NetworkIdentity UniquePlayer;
// On button click, it checks the players position and resets the position if values are true
public void ResetPosition () {
UniquePlayer = GameObject.Find("Player").GetComponent<NetworkIdentity>();
var Player = GameObject.FindWithTag("Player");
// Reset player position if the players Y axis is less than -2
if (Player.transform.position.y < threshold) {
Debug.Log("player position has been reset");
Player.transform.position = new Vector3(0, 1, 0);
} else {
Debug.Log("Player position Y is currently at: " + Player.transform.position.y);
}
}
}
My goal is to catch the unique players y position and reset that to 1 if its less then -2. I got it working when you're in the match alone, but as soon as you're more than 1 player in the match, it does weird things because its not pointing to the specific player.
I'm using NetworkManager and its running on localhost. I've attempted my way around this with getting the netID of the player which is unique but can't figure out how to combine this information.
Hope someone is able to point me in the right direction.
Why don't you just use a MonoBehaviour Script and attach it to the player objects?
By this you already have the right Player GameObject and you don't have to find the GameObject with the Tag.
First I would recommend doing some more testing to narrow down how the weird behavior differs on the host system and the client system. This might give some insight into what exactly is going wrong.
Second, I agree with Sebastian that putting a MonoBehaviour on the player prefab could be a better way to go. Something like this should be a surefire solution:
using UnityEngine;
public class PositionReset : MonoBehaviour {
public float threshold = -2;
public float resetHeight = 1;
private void Update() {
if (transform.position.y < threshold) {
// Note, I keep the x and z position the same, as it sounds like that's what you were looking for. Change as needed
transform.position = new Vector3(transform.position.x, resetHeight, transform.position.z);
}
}
}
If putting the behavior on the player prefab itself isn't acceptable for some reason, here is a modified version of your code snippet that might solve the issue:
using UnityEngine;
using UnityEngine.Networking;
public class ResetPlayerPosition : NetworkManager {
public float threshold = -2f;
// On button click, it checks the players position and resets the position if values are true
public void ResetPosition () {
var Players = GameObject.FindGameObjectsWithTag("Player");
foreach(GameObject Player in Players) {
// Reset player position if the players Y axis is less than -2
if (Player.transform.position.y < threshold) {
Debug.Log("player position has been reset");
Player.transform.position = new Vector3(0, 1, 0);
} else {
Debug.Log("Player position Y is currently at: " + Player.transform.position.y);
}
}
}
}
You'll note that instead of retrieving one game object with the player tag, we retrieve all of them, and perform the evaluation against all of them with the foreach loop. This should yield more consistent behavior.
Beyond this, I would look into using a NetworkTransform, which will help keep the positions of players synced across the network for all movements; an essential tool for almost all networked games.

2D player damage on trigger collider

So I'm making a little top down space shooter and everything works great so far. My issue is that when I change weapons I would like the secondary to do more damage than the primary (changeable with the number keys). It's been a real head scratcher and any help would be greatly appreciated. this is what I tried;
adding the weapons to individual layers. in the OnTriggerEnter2D function I make an if statement stating if the gameObject (bullet) is firing from layer 13, take away x amount of HP. Doesn't do anything though. below is my current code for the enemy.
using UnityEngine;
using System.Collections;
public class enemyDamage : MonoBehaviour {
public int health = 2;
void OnTriggerEnter2D(){
health--;
}
void Start () {
}
void Update () {
if (health <= 0){
Die();
}
}
void Die(){
Destroy (gameObject);
}
}
You can change your OnTriggerEnter2D function by adding Collider2D parameter to it. That way you can get access to the gameObject that triggered the function.
You didn't post the code that is instantiating the bullet. But if you set bullets name to different values you can decrease the health based on that.
void OnTriggerEnter2D(Collider2D other) {
if(other.gameObject.name == "missile"){
health -= 10;
}else if(other.gameObject.name == "bullet"){
health -= 1;
}
}
Or even better idea might be adding a script to the bullet, which knows the amount of damage the bullet is going to make.
void OnTriggerEnter2D(Collider2D other) {
health -= other.gameObject.GetComponent<BulletScript>().damage;
}

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! =)