I am working on a 2D, topdown, roguelike game but i got stuck when i tried to make a shooting system.
when i run it and press the arrow keys, the bullet spawns and points in the right direction. It juste doesn't move in any way.
This is my code and i hope someone can figure it out. Btw, everything is connected. The player and the bullet prefab.
using System.Collections;
using System.Linq;
using UnityEngine;
namespace Assets.Scripts
{
[RequireComponent(typeof(Player))]
public class PlayerShootController : ShootControllerBase
{
[SerializeField]
private int _numberOfBombs;
public int NumberofBombs
{
get { return _numberOfBombs; }
set { _numberOfBombs = value; }
}
[SerializeField]
private PlayerHeadController _headObject;
public PlayerHeadController HeadObject
{
get { return _headObject; }
set { _headObject = value; }
}
[SerializeField]
private Bomb _bombPrefab;
public Bomb BombPrefab
{
get { return _bombPrefab; }
set { _bombPrefab = value; }
}
public bool IsShooting { get; private set; }
private KeyCode _shootKey;
private Vector2 _shootDirection;
private Player _player;
public override void Start()
{
base.Start();
_player = GetComponent<Player>();
}
public override void Update()
{
base.Update();
if (IsShooting)
{
SetHeadDirection(_shootKey);
return;
}
if (InputHelpers.IsAnyKey(KeyCode.UpArrow, KeyCode.DownArrow, KeyCode.LeftArrow, KeyCode.RightArrow))
{
if (Input.GetKey(KeyCode.UpArrow))
{
_shootDirection = new Vector2(0, BulletSpeed);
_shootKey = KeyCode.UpArrow;
}
else if (Input.GetKey(KeyCode.DownArrow))
{
_shootDirection = new Vector2(0, -BulletSpeed);
_shootKey = KeyCode.DownArrow;
}
else if (Input.GetKey(KeyCode.LeftArrow))
{
_shootDirection = new Vector2(-BulletSpeed, 0);
_shootKey = KeyCode.LeftArrow;
}
else if (Input.GetKey(KeyCode.RightArrow))
{
_shootDirection = new Vector2(BulletSpeed, 0);
_shootKey = KeyCode.RightArrow;
}
StartCoroutine(Shoot());
}
if (NumberofBombs > 0 && InputHelpers.IsAnyKeyDown(KeyCode.LeftShift, KeyCode.RightShift, KeyCode.E))
{
var bomb = (Bomb) Instantiate(BombPrefab);
bomb.transform.position = transform.position;
NumberofBombs--;
}
}
IEnumerator Shoot()
{
IsShooting = true;
while (Input.GetKey(_shootKey))
{
var bullet = (Rigidbody2D)Instantiate(BulletPrefab);
bullet.GetComponent<BulletScript>().Shooter = transform.gameObject;
bullet.transform.position = transform.position;
if (_shootDirection.y > 0)
{
bullet.transform.Rotate(0, 0, -90);
}
else if (_shootDirection.y < 0)
{
bullet.transform.Rotate(0, 0, 90);
}
else if (_shootDirection.x > 0)
{
TransformHelpers.FlipX(bullet.gameObject);
}
bullet.AddForce(_shootDirection);
bullet.AddForce(_player.GetComponent<Rigidbody2D>().GetPointVelocity(_player.transform.position) * 0.02f);
if (ShootClips.Any())
{
var clipToPlay = ShootClips[Random.Range(0, ShootClips.Count)];
clipToPlay.pitch = Random.Range(MinShootPitch, MaxShootPitch);
clipToPlay.Play();
}
yield return new WaitForSeconds(ShootingSpeed);
}
IsShooting = false;
//Reset head flipping
if (_headObject.transform.localScale.x < 0)
{
TransformHelpers.FlipX(_headObject.gameObject);
}
}
private void SetHeadDirection(KeyCode shootKey)
{
switch (shootKey)
{
case KeyCode.UpArrow:
_headObject.SetHeadDirection(PlayerHeadController.HeadDirection.Up);
break;
case KeyCode.DownArrow:
_headObject.SetHeadDirection(PlayerHeadController.HeadDirection.Down);
break;
case KeyCode.LeftArrow:
_headObject.SetHeadDirection(PlayerHeadController.HeadDirection.Left);
break;
case KeyCode.RightArrow:
_headObject.SetHeadDirection(PlayerHeadController.HeadDirection.Right);
break;
}
}
}
}
try this:
bullet.AddForce(_shootDirection*moveSpeed*Time.deltaTime);
instead of this:
bullet.AddForce(_shootDirection);
bullet.AddForce(_player.GetComponent<Rigidbody2D>().GetPointVelocity(_player.transform.position) * 0.02f);
tweak the speed for desired result, and if you want the bullet to follow the player you will need to update the shoot direction every certain time with a couroutine
Related
I wanted to add multiplayer to my game but i quickly faced many many problems, i cant find any clear solution online. i made a weapon script where the player can shoot and reload.
problems:
when i shoot, on 1 screen both players shoot, but at the other screen nothing happens
when i swap weapons, on 1 screen both players swap weapons, on the second screen nothing happens
note: im still a complete beginner so go easy on me please :)) thanks!
weapon script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using Photon.Pun;
public class weaponScript : MonoBehaviour
{
public weaponSO weaponStats;
public GameObject reloadingText;
public TMP_Text ammoValue;
public Transform firePoint;
public GameObject bulletPrefab;
public float bulletForce = 2f;
public bool isShooting;
public float pistolDamage;
public int currentAmmoClip = 1;
public int maxAmmoClip;
public int currentReserve = 1;
public int maxReserve;
public float reloadTime = 2f;
public bool isReloading = false;
public int bulletsShot;
public float startingDamage;
PhotonView view;
public void Start()
{
view = GetComponent<PhotonView>();
if(view.IsMine)
{
view.RPC("Update", RpcTarget.AllBuffered);
}
WeaponStats();
currentAmmoClip = maxAmmoClip;
currentReserve = maxReserve;
bulletsShot = maxAmmoClip - currentAmmoClip;
isShooting = false;
weaponStats.damage = startingDamage;
}
[PunRPC]
public void Update()
{
ammoValue.text = currentAmmoClip.ToString("0") + "/" + currentReserve.ToString("0");
if (Input.GetKeyDown(KeyCode.R))
{
if(currentReserve <= 0)
{
return;
}
if (currentAmmoClip == maxAmmoClip && !isReloading)
{
return;
}
else
{
StartCoroutine(Reload());
return;
}
}
if(Input.GetButtonDown("Fire1") && currentAmmoClip >= 1)
{
if(isReloading == false)
{
bulletsShot += 1;
currentAmmoClip -= 1;
isShooting = true;
Shoot();
FindObjectOfType<AudioManager>().Play("shot1");
return;
}
}
if(isReloading)
return;
if(currentAmmoClip <= 0 && currentReserve >= 1)
{
StartCoroutine(Reload());
return;
}
}
IEnumerator Reload()
{
reloadingText.SetActive(true);
isReloading = true;
yield return new WaitForSeconds(reloadTime);
if(currentReserve <= bulletsShot)
{
currentAmmoClip += currentReserve;
currentReserve = 0;
}
else
{
currentReserve -= bulletsShot;
currentAmmoClip = maxAmmoClip;
}
bulletsShot = 0;
reloadingText.SetActive(false);
isReloading = false;
}
void Shoot()
{
GameObject bullet = Instantiate(bulletPrefab, firePoint.position, firePoint.rotation);
Rigidbody2D rb = bullet.GetComponent<Rigidbody2D>();
rb.AddForce(firePoint.up * bulletForce, ForceMode2D.Impulse);
}
public void WeaponStats()
{
pistolDamage = weaponStats.initialDamage;
maxAmmoClip = weaponStats.maxAmmoClip;
maxReserve = weaponStats.maxReserve;
reloadTime = weaponStats.reloadTime;
bulletForce = weaponStats.bulletForce;
startingDamage = weaponStats.initialDamage;
}
}
weapon holder:
using UnityEngine;
public class WeaponHolder : MonoBehaviour
{
public int selectedWeapon = 0;
void Start()
{
SelectWeapon();
}
void Update()
{
if(FindObjectsOfType<weaponScript>()[0].isReloading == true)
{
return;
}
else
{
switchWeapon();
}
}
public void switchWeapon()
{
int previousSelectedWeapon = selectedWeapon;
if(Input.GetAxis("Mouse ScrollWheel") > 0f)
{
if(selectedWeapon >= transform.childCount - 1)
{
selectedWeapon = 0;
}
else
{
selectedWeapon++;
}
}
if(Input.GetAxis("Mouse ScrollWheel") < 0f)
{
if(selectedWeapon <= 0)
{
selectedWeapon = transform.childCount - 1;
}
else
{
selectedWeapon--;
}
}
if(previousSelectedWeapon != selectedWeapon)
{
SelectWeapon();
}
}
public void SelectWeapon()
{
int i = 0;
foreach (Transform weapon in transform)
{
if(i == selectedWeapon)
{
weapon.gameObject.SetActive(true);
}
else
{
weapon.gameObject.SetActive(false);
}
i++;
}
}
}
i tried adding
if(view.IsMine == true)
{
Debug.Log("true");
}
else
{
Debug.Log("false");
}
but nothing happened and i couldnt shoot anymore. thanks for reading
The problem is you don't sync anything in your game. This means the other computer can't know what it has to do.
Whenever you want to sync something you have to call an RPC function.
Maybe watch some tutorials about how to do this properly and how to set up a simple multiplayer lobby.
EDIT:
What the other comments above mentioned with .IsMine is true, but you're doing it wrong. You have to call this in start or awake and whenever the view is not yours you disable the camera of the person only and disable shooting. Its important to only do this on your computer! If you are not doing everyone will shoot when you press Shoot and everyone will walk when you walk.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class loadingcolorful : MonoBehaviour
{
public float speed = 0.0f;
public bool fillAmount = false;
public bool rotate = false;
public bool changeRotationDir = false;
public bool changeFillDir = false;
private RectTransform rectTransform;
private Image imageComp;
// Use this for initialization
void Start()
{
imageComp = GetComponent<RectTransform>().GetComponent<Image>();
rectTransform = transform.parent.gameObject.transform.GetComponent<RectTransform>();
}
// Update is called once per frame
void Update()
{
if (fillAmount == true)
{
if (imageComp.fillAmount != 1f)
{
if (changeFillDir == true)
{
imageComp.fillAmount -= speed;
}
else
{
imageComp.fillAmount += speed;
}
}
else
{
imageComp.fillAmount = 0f;
}
}
else
{
if (imageComp.fillAmount == 0f)
{
imageComp.fillAmount = 0f;
}
else
{
imageComp.fillAmount = 1f;
}
}
if (rotate == true)
{
if (changeRotationDir == true)
{
rectTransform.Rotate(new Vector3(0, 0, -1));
}
else
{
rectTransform.Rotate(new Vector3(0, 0, 1));
}
}
}
}
The problem is at this place :
if (changeFillDir == true)
{
imageComp.fillAmount -= speed;
}
When it will get to 0 it will not continue to fill the image to the other direction just the image will stay empty. My guess is that the values of the FillAmount ragne is between 1 and 0.
Is there a way to make it happen ?
It's a bit of a hack, but you can switch to a negative scale value and start increasing the fillAmout again. This will make it fill in the other direction, taking the 0 point as pivot.
Assuming you are filling horizontally, flipping the scale would look something like this:
transform.localScale = new Vector3(-1, 1, 1);
A working solution like I wanted :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class loadingcolorful : MonoBehaviour
{
public float speed = 0.0f;
public bool fillAmount = false;
public bool rotate = false;
public bool changeRotationDir = false;
public bool changeFillDir = false;
public bool useBackGroundImage = true;
private RectTransform rectTransform;
private Image imageComp;
private Image backGroundImage;
// Use this for initialization
void Start()
{
imageComp = GetComponent<RectTransform>().GetComponent<Image>();
backGroundImage = transform.parent.gameObject.transform.GetComponent<Image>();
UseBackgImage();
}
// Update is called once per frame
void Update()
{
UseBackgImage(useBackGroundImage);
if (fillAmount == true)
{
if (imageComp.fillAmount != 1f)
{
if (changeFillDir == true)
{
if (imageComp.fillAmount == 0)
{
imageComp.fillAmount = 1f;
}
imageComp.fillAmount -= speed;
}
else
{
imageComp.fillAmount += speed;
}
}
else
{
imageComp.fillAmount = 0f;
}
}
else
{
if (imageComp.fillAmount == 0f)
{
imageComp.fillAmount = 0f;
}
else
{
imageComp.fillAmount = 1f;
}
}
if (rotate == true)
{
if (changeRotationDir == true)
{
rectTransform.Rotate(new Vector3(0, 0, -1));
}
else
{
rectTransform.Rotate(new Vector3(0, 0, 1));
}
}
}
private void UseBackgImage()
{
if (useBackGroundImage == true)
{
backGroundImage.enabled = true;
rectTransform = transform.parent.gameObject.transform.GetComponent<RectTransform>();
}
else
{
backGroundImage.enabled = false;
rectTransform = transform.GetComponent<RectTransform>();
}
}
private void UseBackgImage(bool UseBackGroundImage)
{
if (useBackGroundImage == true)
{
backGroundImage.enabled = true;
}
else
{
backGroundImage.enabled = false;
}
}
}
I'm trying to make use of the Blur effect but I'm getting an error reading that the the type or namespace cannot be found. Thanks in advance.
I'm new to unity so I apologize if this is an easy fix. Here is a screenshot of my code.
using UnityEngine;
using System.Collections;
using UnityStandardAssets.Characters.FirstPerson;
using UnityStandardAssets.ImageEffects;
using System;
using System.Reflection;
using Assets.SwimmingSystem.Scripts;
namespace Assets.SwimmingSystem.Scripts
{
public class Swim : MonoBehaviour
{
private FirstPersonController _firstPersonController;
private CharacterController _characterController;
private Blur _blur;
private Color _fogColorWater;
// Default settings on start
private float _defWalkspeed, _defJumpspeed, _defRunspeed, _defGravityMultiplier;
private FogMode _defFogMode;
private float _defFogDensity;
private Color _defFogColor;
private bool _defFogEnabled;
private Camera _camera;
private bool _isInWater = false;
private float _waterSurfacePosY = 0.0f;
public float _aboveWaterTolerance = 0.5f;
[Range(0.5f, 3.0f)]
public float _upDownSpeed = 1.0f;
// Use this for initialization
void Start()
{
_firstPersonController = GetComponent<FirstPersonController>();
_characterController = GetComponent<CharacterController>();
_fogColorWater = new Color(0.2f, 0.65f, 0.75f, 0.5f);
Transform fpChar = transform.FindChild("FirstPersonCharacter");
_blur = fpChar.GetComponent<Blur>();
_camera = fpChar.GetComponent<Camera>();
// Default values for FirstPersonController on start
_defWalkspeed = WalkSpeed;
_defRunspeed = RunSpeed;
_defJumpspeed = JumpSpeed;
_defGravityMultiplier = GravityMultiplier;
_defFogMode = RenderSettings.fogMode;
_defFogDensity = RenderSettings.fogDensity;
_defFogColor = RenderSettings.fogColor;
_defFogEnabled = RenderSettings.fog;
}
// Update is called once per frame
void Update()
{
// Set underwater rendering or default
if (IsUnderwater())
{
SetRenderDiving();
}
else
{
SetRenderDefault();
}
// Handle swimming
// 1. If camera underwater we dive
if (_isInWater)
{
if (IsUnderwater())
{
DoDiving();
}
else
{
// we are grounded and not underwater, we might walk as well
if (_characterController.isGrounded)
{
DoWalking();
}
else
{
// we are not grounded so we are swimming above the surface
HandleUpDownSwimMovement();
}
}
}
else
{
DoWalking();
}
}
// Check if we are underwater
private bool IsUnderwater()
{
return _camera.gameObject.transform.position.y < (_waterSurfacePosY);
}
// Let's walk
private void DoWalking()
{
StickToGroundForce = 10;
WalkSpeed = Mathf.Lerp(WalkSpeed, _defWalkspeed, Time.deltaTime * 3.0f);
RunSpeed = Mathf.Lerp(RunSpeed, _defRunspeed, Time.deltaTime * 3.0f);
JumpSpeed = _defJumpspeed;
GravityMultiplier = _defGravityMultiplier;
UserHeadBob = true;
}
// Let's dive
private void DoDiving()
{
WalkSpeed = 1.0f;
RunSpeed = 2.0f;
JumpSpeed = 0.0f;
UserHeadBob = false;
HandleUpDownSwimMovement();
}
private void HandleUpDownSwimMovement()
{
StickToGroundForce = 0.0f;
GravityMultiplier = 0.1f;
Vector3 mv = MoveDir;
if (Input.GetKey(KeyCode.E))
{
// go upwards
if (_camera.gameObject.transform.position.y < _waterSurfacePosY + _aboveWaterTolerance)
{
mv.y = _upDownSpeed;
}
}
else if (Input.GetKey(KeyCode.Q))
{
// go down
mv.y = -_upDownSpeed;
}
MoveDir = mv;
}
// Rendering when diving
private void SetRenderDiving()
{
RenderSettings.fog = true;
RenderSettings.fogColor = _fogColorWater;
RenderSettings.fogDensity = 0.1f;
RenderSettings.fogMode = FogMode.Exponential;
_blur.enabled = true;
}
// Rendering when above water
private void SetRenderDefault()
{
RenderSettings.fogColor = _defFogColor;
RenderSettings.fogDensity = _defFogDensity;
RenderSettings.fog = _defFogEnabled;
RenderSettings.fogMode = _defFogMode;
_blur.enabled = false;
}
public void OnTriggerEnter(Collider other)
{
if (LayerMask.LayerToName(other.gameObject.layer) == "Water")
{
// We enter the water... doesn't matter if we return from unserwater, we are still in the water
_isInWater = true;
Debug.Log("Water Trigger Enter : " + _isInWater);
}
}
public void OnTriggerExit(Collider other)
{
if (LayerMask.LayerToName(other.gameObject.layer) == "Water" && _isInWater)
{
// we are leaving the water, or are we under the sureface?
_waterSurfacePosY = other.transform.position.y;
float fpsPosY = this.transform.position.y;
if (fpsPosY > _waterSurfacePosY)
{
// ok we really left the water
_isInWater = false;
}
Debug.Log("Water Trigger Exit : " + _isInWater);
}
}
#region Properties by reflection
private Vector3 MoveDir
{
get
{
return (Vector3)ReflectionUtil.GetFieldValue(_firstPersonController, "m_MoveDir");
}
set
{
ReflectionUtil.SetFieldValue(_firstPersonController, "m_MoveDir", value);
}
}
public float WalkSpeed
{
get
{
return (float)ReflectionUtil.GetFieldValue(_firstPersonController, "m_WalkSpeed");
}
set
{
ReflectionUtil.SetFieldValue(_firstPersonController, "m_WalkSpeed", value);
}
}
public float RunSpeed
{
get
{
return (float)ReflectionUtil.GetFieldValue(_firstPersonController, "m_RunSpeed");
}
set
{
ReflectionUtil.SetFieldValue(_firstPersonController, "m_RunSpeed", value);
}
}
public float JumpSpeed
{
get
{
return (float)ReflectionUtil.GetFieldValue(_firstPersonController, "m_JumpSpeed");
}
set
{
ReflectionUtil.SetFieldValue(_firstPersonController, "m_JumpSpeed", value);
}
}
public float GravityMultiplier
{
get
{
return (float)ReflectionUtil.GetFieldValue(_firstPersonController, "m_GravityMultiplier");
}
set
{
ReflectionUtil.SetFieldValue(_firstPersonController, "m_GravityMultiplier", value);
}
}
public float StickToGroundForce
{
get
{
return (float)ReflectionUtil.GetFieldValue(_firstPersonController, "m_StickToGroundForce");
}
set
{
ReflectionUtil.SetFieldValue(_firstPersonController, "m_StickToGroundForce", value);
}
}
public bool UserHeadBob
{
get
{
return (bool)ReflectionUtil.GetFieldValue(_firstPersonController, "m_UseHeadBob");
}
set
{
ReflectionUtil.SetFieldValue(_firstPersonController, "m_UseHeadBob", value);
}
}
#endregion
}
}
Make sure you are using the pro version of unity to make use of ImageEffects feature.
"The Blur image effect blurs the rendered image in real-time.
As with the other image effects, this effect is only available in Unity Pro and you must have the Pro Standard Assets installed before it becomes available."
Taken from : https://docs.unity3d.com/462/Documentation/Manual/script-BlurEffect.html
as the titel say's I'm trying to make a game in Monogame, a Bomberman clone, but atm when I try to spawn more then one bomb the animation just moves to the new location. The game object stays where it is supposed to, but it does not have the animation. I think the problem is that it loads the same animation which has been loaded but I just cant seem to figure out how to get it to spawn a new animation everytime a bomb spawns.
I use Content.Load to get the sorite animation, and spawn the bomb with a clone() function with the animation.
var bombAni = new Dictionary<string, Animation>() {
{"Bomb", new Animation(Content.Load<Texture2D>("Obstacle/Bomb"), 3) },
};
_sprites = new List<Sprite>() {
new Player(animations) {
_bomb = new Bomb(bombAni),
Position = new Vector2(32, 32),
Input = new Input() {
Up = Keys.W,
Down = Keys.S,
Left = Keys.A,
Right = Keys.D,
Space = Keys.Space,
}
}
};
public void Play(Animation animation) {
if (animation == _animation) {
return;
}
_animation = animation;
_animation.CurFrame = 0;
_timer = 0;
}
private void AddBomb(List<Sprite> sprites) {
var bomb = _bomb.Clone() as Bomb;
switch (_direction) {
case "Up":
bomb.Position = _position + new Vector2(0, -32);
break;
case "Down":
bomb.Position = _position + new Vector2(0, 32);
break;
case "Left":
bomb.Position = _position + new Vector2(-32, 0);
break;
case "Right":
bomb.Position = _position + new Vector2(32, 0);
break;
}
bomb.lifeSpan = 3f;
bomb.Parent = this;
bombCount++;
sprites.Add(bomb);
}
public Sprite(Dictionary<string, Animation> animations) {
_animations = animations;
_animationManager = new AnimationManager(_animations.First().Value);
}
namespace CompetenceWeek.scripts {
public class Bomb : Sprite {
public float lifeSpan;
private float _timer;
public Bomb(Dictionary<string, Animation> animations) : base(animations) {
}
public Bomb(Texture2D texture) : base(texture) {
}
public override void Update(GameTime gameTime, List<Sprite> sprites) {
_timer += (float)gameTime.ElapsedGameTime.TotalSeconds;
SetAnimations();
_animationManager.Update(gameTime);
if (_timer > lifeSpan) {
isDead = true;
}
}
}
}
namespace CompetenceWeek.scripts {
public class Sprite : ICloneable {
protected AnimationManager _animationManager;
protected Dictionary<string, Animation> _animations;
protected Vector2 _position;
protected Texture2D _texture;
public bool Walkable { get; set; } = false;
public bool isDead = false;
public Player Parent { get; set; }
public Input Input;
public Vector2 Position {
get { return _position; }
set {
_position = value;
if(_animationManager != null) {
_animationManager.Posistion = _position;
}
}
}
public float Speed = 2.5f;
public Vector2 Velocity;
public virtual void Draw(SpriteBatch spriteBatch) {
if(_texture != null) {
spriteBatch.Draw(_texture, Position, Color.White);
} else if (_animationManager != null) {
_animationManager.Draw(spriteBatch);
} else {
throw new Exception("somthings not right");
}
}
public Sprite(Dictionary<string, Animation> animations) {
_animations = animations;
_animationManager = new AnimationManager(_animations.First().Value);
}
public Sprite(Texture2D texture) {
_texture = texture;
}
public virtual void Update(GameTime gameTime, List<Sprite> sprites) {
SetAnimations();
_animationManager.Update(gameTime);
Position += Velocity;
Velocity = Vector2.Zero;
}
protected virtual void SetAnimations() {
if (Velocity.X > 0) {
_animationManager.Play(_animations["PlayerRight"]);
} else if (Velocity.X < 0) {
_animationManager.Play(_animations["PlayerLeft"]);
} else if (Velocity.Y > 0) {
_animationManager.Play(_animations["PlayerDown"]);
} else if (Velocity.Y < 0) {
_animationManager.Play(_animations["PlayerUp"]);
}
}
public object Clone() {
return this.MemberwiseClone();
}
}
}
The problem is with this segment:
protected Dictionary<string, Animation> _animations;
public object Clone() {
return this.MemberwiseClone();
}
When you perform a memberwise clone, it creates a shallow copy, reusing existing references to reference-type objects. This means that the Clone will share the same animation state with the original object.
The solution to this, is to instantiate a new copy of all of the Animations every time you want to clone Bomb.
Something like this:
public object Clone() {
var bomb = (Bomb)this.MemberwiseClone();
bomb.InitAnimations(new Dictionary<string, Animation>() {
{"Bomb", new Animation(Content.Load<Texture2D>("Obstacle/Bomb"), 3) },
};
return bomb;
}
i already make the player character to move to it is destination (animate the character to move to that destination), i wanted to disable the GUI button when the player character is moving, but i can't get it and work it out. Could you guys help me?
Here is the code:
public class UserPlayer : Player
{
public override void TurnUpdate()
{
//Moving animation
if (positionQueue.Count > 0)
{
GUI.enabled = false; // This is the one that i want when the character still moving (animation still moving), disabled the GUI. But i can't get it
transform.position += (positionQueue[0] - transform.position).normalized * moveSpeed * Time.deltaTime;
if (Vector3.Distance(positionQueue[0], transform.position) <= 0.1f)
{
transform.position = positionQueue[0];
positionQueue.RemoveAt(0);
if (positionQueue.Count == 0)
{
actionPoints--;
}
}
}
base.TurnUpdate();
}
public override void TurnOnGUI()
{
base.TurnOnGUI();
}
}
public class Player : MonoBehaviour
{
//for movement animation
public List<Vector3> positionQueue = new List<Vector3>();
public virtual void TurnUpdate()
{
if (actionPoints <= 0)
{
actionPoints = 2;
magicAttacking = false;
moving = false;
attacking = false;
GameManager.instance.NextTurn();
}
}
public virtual void TurnOnGUI()
{
if (GameManager.instance.currentPlayerIndex == 0 || GameManager.instance.currentPlayerIndex == 2)
{
//ToolTip Text
move = GUI.Button(buttonRect, new GUIContent("Move", "Move the Player"));
GUI.Label(tooltipRect, GUI.tooltip, label1);
GUI.tooltip = null;
//Move Button
if (move)
{
if (!moving)
{
GameManager.instance.RemoveTileHighlights();
moving = true;
attacking = false;
GameManager.instance.HighlightTilesAt(gridPosition, Color.blue, movementPerActionPoint);
}
else
{
moving = false;
attacking = false;
GameManager.instance.RemoveTileHighlights();
}
}
}
Your question has been already made, take a look here.
Adapt your code in this way:
public virtual void TurnOnGUI() {
if (GameManager.instance.currentPlayerIndex == 0 || GameManager.instance.currentPlayerIndex == 2) {
...
if(!moving) {
move = GUI.Button(buttonRect, new GUIContent("Move", "Move the Player"));
GUI.Label(tooltipRect, GUI.tooltip, label1);
}
...
}
}