Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Kadaiyen · Jul 24, 2012 at 09:55 PM · c#pathwaypointloops

Script to Tell if Circuit / Path is Complete

Thanks for clicking!

What I'm trying to do is create a game reminiscient of Pipe Dream, and those little plastic picture slider puzzles. The point is to complete a path from the start block to the end block. Each block has an invisible "waypoint" block that collides with nothing, and is used simply for raycasts - it's how the player moves, snapping from block to block. The player can't move unless the block he's on and the block he wants to move to are connected by open sides.

Here's a screenshot for context:

http://i.imgur.com/RhBXb.png (link because the built-in image uploader on the questions form keeps popping up the picture in front of the "accept" button, rendering it unacceptable :P)

Basically, using the way points and raycasting method of moving my character, I'm trying to write a script that checks for whether an unbroken path between the start and finish has been made. Unfortunately, the script I've written has led to infinite loops, array out of bounds, and some other strange freezing issues with debug enabled and viewing the object with said script (?!?). Point is, it doesn't work - I feel like I'm close, but after 5 hours of tinkering, I haven't been able to get it functional.

That's where you come in, if you'd be so kind; here's the script, if anybody could give me tips on:

  1. What I'm doing wrong

  2. A better way of doing it

  3. General issues you find

I'd very much appreciate it.

Here's the script, as is:

using UnityEngine; using System.Collections; using System.Collections.Generic;

public class CheckVictoryConditions : MonoBehaviour {

  private bool foundOpens;
  private bool victory;
  private int timeCount;
  private int tilesIndex;
  private Tile curTile;
  private List<Tile> tiles = new List<Tile>();
 
  // helper
  [System.Serializable]
  public class Tile {
  public Transform transform;
  public bool checkedDirs = false;
  public Tile[] opens = new Tile[4];
 
  public Tile(Transform t) {
  this.transform = t;
  this.checkedDirs = false;
  for (int i = 0; i < 4; i++) {
  opens[i] = null;
  }
  }
  }
 
  // Use this for initialization
  void Start() {
  victory = false;
  foundOpens = false;
  timeCount = 0;
  tilesIndex = 0;
  curTile = new Tile(GameObject.Find("Tile_Start").GetComponent<Transform>());
  tiles.Add(curTile);
  Debug.Log(curTile.transform);
  }
 
  // Update is called once per frame
  void Update() {
  //while (CheckAnyOpens() == true) {
  if (CheckAnyOpens() == true) {
  curTile.opens = CheckTile(curTile); // check current tile
  if (foundOpens == true) {
  PickTile(curTile);
  foundOpens = false;
  }
  SetTile(curTile, tilesIndex); // set tile up or down
  if (curTile.transform.name == "Tile_Finish") {
  victory = true;
  //break;
  }
  }
  //}
 
  if (curTile.transform.name == "Tile_Finish") {
  victory = true;
  }
  //Debug.Log(victory);
  }
 
  void ShiftTileIndex(Tile tile) {
  // shift the working tile index
  if (tile.opens[0] != null || tile.opens[1] != null || tile.opens[2] != null || tile.opens[3] != null) {
  tilesIndex += 1;
  foundOpens = true;
  }
  else {
  tilesIndex -= 1;
  foundOpens = false;
  if (tilesIndex < 0) {
  tilesIndex = 0;
  }
  }
  }
 
  void PickTile(Tile tile) {
  for (int i = 0; i < 4; i++) {
  if (tile.opens[i] != null && tile.opens[i].checkedDirs == false) {
  tile = tile.opens[i];
  tiles.Add(tile);
  }
  }
  }
 
  void SetTile(Tile tile, int index) {
  if (index >= 0) {
  tile = tiles[index];
  }
  }
 
  // Goes through levels and checks if there are any remaining open paths to check
  bool CheckAnyOpens() {
  bool anyOpens = false;
  for (int i = 0; i < tiles.Count; i++) {
  for (int k = 0; k < 4; k++) {
  if (tiles[i].opens[k] != null && tiles[i].opens[k].checkedDirs == false) {
  anyOpens = true;
  break;
  }
  }
  }
  Debug.Log("anyOpens = " + anyOpens);
  return anyOpens;
  }
  // For current tile, checks each of the 4 directions for an open path, returns positions of waypoints for the open
  // paths so that they can be checked for paths as well
  Tile[] CheckTile(Tile tile) {
  Debug.Log("CheckTile");
  // should check to see if the tile is already listed in tiles or not, and if so, returns current opens
  //foreach (Tile t in tiles) {
  //    if (t.transform.position == curTile.transform.position) {
  //        Debug.Log("Already have this tile");
  //        return curTile.opens;
  //    }
  //}
  Tile[] opens = new Tile[4];
  for (int i = 0; i < 4; i++) {
  opens[i] = null;
  }
 
  RaycastHit hit;
  int targetLayer = 9;
 
  // In order W, A, S, D
  Physics.Raycast(tile.transform.position + Vector3.forward, Vector3.forward, out hit, Mathf.Infinity);
  if (hit.transform.gameObject.layer == targetLayer) {
  opens[0] = new Tile(hit.transform);
  Debug.Log("Open path W");
  }
  Physics.Raycast(tile.transform.position + -Vector3.right, -Vector3.right, out hit, Mathf.Infinity);
  if (hit.transform.gameObject.layer == targetLayer) {
  opens[1] = new Tile(hit.transform);
  Debug.Log("Open path A");
  }
  Physics.Raycast(tile.transform.position + -Vector3.forward, -Vector3.forward, out hit, Mathf.Infinity);
  if (hit.transform.gameObject.layer == targetLayer) {
  opens[2] = new Tile(hit.transform);
  Debug.Log("Open path S");
  }
  Physics.Raycast(tile.transform.position + Vector3.right, Vector3.right, out hit, Mathf.Infinity);
  if (hit.transform.gameObject.layer == targetLayer) {
  opens[3] = new Tile(hit.transform);
  Debug.Log("Open path D");
  }
 
  ShiftTileIndex(tile);
 
  tile.checkedDirs = true;
  return opens;
  }
 }

The idea was to deal with it like this: the computer would start at the Start block, check for open paths in the four directions (WASD, or up down left right), and if there were any, store them in an array. It would also move the tilesIndex up one, so that when I ran into a block with no open paths, I could just move back one using the tiles list.

From there, I'd pick one of the open paths on this block, then move to the block in that direction, and repeat the process. Each time I check a block I'd mark it as "checked" so that I wouldn't end up bouncing back and forth between two blocks. On paper it seems like this should run through every block connected to the Start block when it's called, but if it's not giving me an infinite loop or crashing Unity, it's not advancing blocks properly or something. I'm really not sure.

I hope that's enough information. Thanks :)

Note: I know the code is probably pretty poorly done, if there's anything confusing or lacking in description, I'll be sure to add to the description.

Note2: Apparently it doesn't want to keep the code's formatting. Sorry. :|

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

0 Replies

· Add your reply
  • Sort: 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Need an advise to upgrade my code!!! 1 Answer

How to select adjacent cubes along edges? 2 Answers

How to make AI wonder about? C#? 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges