Search Unity

2d Roguelike tutorial customize?

Discussion in 'Scripting' started by leegod, Apr 13, 2015.

  1. leegod

    leegod

    Joined:
    May 5, 2010
    Posts:
    2,476
    At Official tutorial video and script.

    How can I make enemy interact also with Wall like player?

    So I want to add logic when enemy meet wall, enemy can damage it and destroy it.

    But OnCantMove<T> only receive one type?

    How should I revise?
     
    Last edited: Apr 13, 2015
  2. psyydack

    psyydack

    Joined:
    Aug 30, 2013
    Posts:
    93
    You can change MovingScript in this line ( not tested, maybe have some sintax errors ):

    protected abstract void OnCantMove <T> (T component, YourType newComponent)
    where T : Component;

    or you can add another event :

    protected abstract void OnCantMoveEnemy <T> (T component, YourType newComponent)
    where T : Component;
     
  3. leegod

    leegod

    Joined:
    May 5, 2010
    Posts:
    2,476
    I did like this,
    Seems not work...

    Enemy.cs

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Enemy : MovingObject {
    5.     public int playerDamage;
    6.     private Animator animator;
    7.     private Transform target;
    8.     private bool skipMove;
    9.     public AudioClip enemyAttack1;
    10.     public AudioClip enemyAttack2;
    11.     protected override void Start () {
    12.         GameManager.instance.AddEnemyToList(this);
    13.         animator = GetComponent<Animator>();
    14.         target = GameObject.FindGameObjectWithTag("Player").transform;
    15.         base.Start();
    16.     }
    17.     protected override void AttemptMove<T> (int xDir, int yDir){
    18.         if(skipMove){
    19.             skipMove = false;
    20.             return;
    21.         }
    22.         base.AttemptMove<T>(xDir, yDir);
    23.  
    24.         skipMove = true;
    25.  
    26.     }
    27.     public void MoveEnemy(){
    28.         int xDir = 0;        int yDir = 0;
    29.         if((Mathf.Abs(target.position.x - transform.position.x) > float.Epsilon)){
    30.             xDir = target.position.x > transform.position.x ? 1 : -1;
    31.         }
    32.         if(Mathf.Abs(target.position.y - transform.position.y) > float.Epsilon){
    33.             yDir = target.position.y > transform.position.y ? 1 : -1;
    34.         }  
    35.         Debug.Log("ydir is "+yDir+" / xdir is "+xDir);
    36.         AttemptMove<Player>(xDir, yDir);
    37.         AttemptMove<Wall>(xDir, yDir);
    38.     }
    39.  
    40.     protected override void OnCantMove<T>(T component){
    41.         Player hitPlayer = component as Player;
    42.         animator.SetTrigger("enemyAttack");
    43.         hitPlayer.LoseFood(playerDamage);
    44.          SoundManager.instance.RandomizeSfx(enemyAttack1, enemyAttack2);
    45.     }
    46.     protected override void OnCantMoveEnemy<T>(T component){
    47.         Wall hitWall = component as Wall;
    48.         Debug.Log("hit wall is "+hitWall.name);
    49.     }
    50. }
    51.  
    MovingObject.cs

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public abstract class MovingObject : MonoBehaviour {
    5.     public float moveTime = 0.1f;
    6.     public LayerMask blockingLayer;
    7.     private BoxCollider2D boxCollider;
    8.     private Rigidbody2D rb2D;
    9.     private float inverseMoveTime;
    10.  
    11.     // Use this for initialization
    12.     protected virtual void Start () {
    13.         boxCollider = GetComponent<BoxCollider2D>();
    14.         rb2D = GetComponent<Rigidbody2D>();
    15.         inverseMoveTime = 1f / moveTime;
    16.     }
    17.     protected bool Move(int xDir, int yDir, out RaycastHit2D hit){
    18.         Vector2 start = transform.position;
    19.         Vector2 end = start+new Vector2(xDir, yDir);
    20.         boxCollider.enabled = false;
    21.         hit = Physics2D.Linecast(start, end, blockingLayer);
    22.         boxCollider.enabled = true;
    23.         if(hit.transform == null){
    24.             StartCoroutine(SmoothMovement(end));
    25.             return true;
    26.         }
    27.         return false;
    28.     }
    29.     protected IEnumerator SmoothMovement(Vector3 end){
    30.         float sqrRemainingDistance = (transform.position-end).sqrMagnitude;
    31.         while(sqrRemainingDistance > float.Epsilon){
    32.             Vector3 newPosition = Vector3.MoveTowards(rb2D.position, end, inverseMoveTime * Time.deltaTime);
    33.             rb2D.MovePosition(newPosition);
    34.             sqrRemainingDistance = (transform.position-end).sqrMagnitude;
    35.             yield return null;
    36.         }
    37.     }
    38.     protected virtual void AttemptMove<T> (int xDir, int yDir) where T : Component{
    39.         RaycastHit2D hit;
    40.         bool canMove = Move (xDir, yDir, out hit);
    41.         if(hit.transform == null)
    42.             return;
    43.  
    44.         T hitComponent = hit.transform.GetComponent<T>();
    45.  
    46.         if(!canMove && hitComponent != null){
    47.             OnCantMove(hitComponent);
    48.             if(hitComponent is Wall)
    49.                 OnCantMoveEnemy(hitComponent);
    50.         }
    51.     }
    52.  
    53.     protected abstract void OnCantMove<T> (T component)    where T : Component;
    54.     protected abstract void OnCantMoveEnemy <T> (T component)    where T : Component;
    55. }
    56.  
     
  4. psyydack

    psyydack

    Joined:
    Aug 30, 2013
    Posts:
    93
    But what not work? What errors that did print? What line in player should do the same in enemy?
    It's looks right to me. =/
     
  5. leegod

    leegod

    Joined:
    May 5, 2010
    Posts:
    2,476
    Enemy.cs's OnCantMoveEnemy<T> doesn't be called.
     
  6. psyydack

    psyydack

    Joined:
    Aug 30, 2013
    Posts:
    93
    Is entering in this if statement?

    Moving.cs
    Code (CSharp):
    1. if(!canMove && hitComponent != null){
    2.             OnCantMove(hitComponent);
    3.             if(hitComponent is Wall)
    4.                 OnCantMoveEnemy(hitComponent);
    5.         }
     
  7. leegod

    leegod

    Joined:
    May 5, 2010
    Posts:
    2,476
    yes OnCantMove(hitComponent); is called.
     
  8. psyydack

    psyydack

    Joined:
    Aug 30, 2013
    Posts:
    93
    And about your
    Code (CSharp):
    1. if(hitComponent is Wall)
    2.                 OnCantMoveEnemy(hitComponent);
    What kind of hitComponent is ?
     
  9. leegod

    leegod

    Joined:
    May 5, 2010
    Posts:
    2,476
    Anyway, I solved on my way. I revised function.

    Code (CSharp):
    1. protected virtual void AttemptMove(int xDir, int yDir){
    2.         RaycastHit2D hit;
    3.         bool canMove = Move (xDir, yDir, out hit);
    4.         if(hit.transform == null)
    5.             return;
    6.        
    7.         GameObject hitComponent = hit.transform.gameObject;
    8.        
    9.         if(!canMove && hitComponent != null){
    10.             //OnCantMove(hitComponent);
    11.             Debug.Log("hit object name is "+hitComponent.name);
    12.             if(hitComponent.GetComponent<Wall>() != null){
    13.                 Component hitCom = hitComponent.GetComponent<Wall>();
    14.                 OnCantMove(hitCom);
    15.             }
    16.             else if(hitComponent.GetComponent<Player>() != null){
    17.                 Component hitCom2 = hitComponent.GetComponent<Player>();
    18.                 OnCantMove(hitCom2);
    19.             }
    20.         }
    21.     }
     
    psyydack likes this.