unity 陶瓷质感_Unity2D:简单自动瓷砖(Tile)的实现
unity2017官方已经支持了瓷砖,但我自己也写了个简单的自动瓷砖,权当学习,效果如图。
image
主要实现了两个功能:
① 根据周围格子的状态改变自己的状态
② 对2D物理碰撞体进行自动合并,优化性能
基本思路是遍历特定范围中的每个GameObjec,然后计算坐标,再通过坐标来处理瓷砖间的相对关系。先看基类,主要处理变换坐标的工作:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AutoTile : MonoBehaviour
{
/* 图块边长 */
public float sideLength;
/* 是否合并碰撞体 */
public bool isCoillder;
/* 左下角的起始块,标定开始计算的位置 */
public GameObject startOne;
/* 存储地图 */
List mapContainer = new List();
protected Transform[] childrenTransforms;
/* 存储子物体 */
protected Vector2 basePoint;
/* 从startone获取的起点 */
/* 初始化起点 */
protected void intinalBasePoint()
{
basePoint = startOne.transform.position;
/* Debug.Log ("BasePoint=" + basePoint); */
}
/* 初始化存储块信息的变长数组 */
protected void intinalMapContainer()
{
/* 获取子物体的数组 */
childrenTransforms = GetComponentsInChildren ( false );
foreach ( Transform tra in childrenTransforms )
{
/* 利用tag判断是否纳入计算 */
if ( tra.tag == "Tile" )
{
Vector2 pos = tra.position;
int x, y;
x = (int) ( (pos.x - basePoint.x) / sideLength + 0.05f);
/* 加0.05防止误差 */
y = (int) ( (pos.y - basePoint.y) / sideLength + 0.05f);
/* 判断是否延长主组 */
while ( mapContainer.Count <= x )
{
mapContainer.Add( new ArrayList() );
}
/* 向列数组填充元素 */
while ( mapContainer [x].Count <= y )
{
mapContainer [x].Add( 0 );
}
mapContainer [x][y] = 1;
}
}
return;
}
/* 以下has***函数是用来判断的工具函数,在子类中用到 */
protected bool hasUp( int x, int y )
{
if ( x < 0 || y < 0 )
return(false);
if ( !(mapContainer.Count > x) || mapContainer [x] == null )
return(false);
if ( mapContainer [x].Count == y + 1 )
return(false); else
return( ( (int) mapContainer [x] [y + 1]) == 1);
}
protected bool hasDown( int x, int y )
{
if ( x < 0 || y < 1 )
return(false);
if ( !(mapContainer.Count > x) || mapContainer [x] == null )
return(false);
return( (int) mapContainer [x] [y - 1] == 1);
}
protected bool hasLeft( int x, int y )
{
if ( x < 1 || y < 0 )
return(false);
if ( !(mapContainer.Count > x) )
return(false);
if ( mapContainer [x - 1] == null || mapContainer [x - 1].Count < y + 1 )
return(false);
return( (int) mapContainer [x - 1] [y] == 1);
}
protected bool hasRight( int x, int y )
{
if ( x < 0 || y < 0 )
return(false);
if ( !(mapContainer.Count > x + 1) )
return(false);
if ( mapContainer [x + 1] == null || mapContainer [x + 1].Count < y + 1 )
return(false);
return( (int) mapContainer [x + 1] [y] == 1);
}
protected bool hasLeftUp( int x, int y )
{
return(hasLeft( x, y + 1 ) );
}
protected bool hasRightUp( int x, int y )
{
return(hasRight( x, y + 1 ) );
}
protected bool hasLeftDown( int x, int y )
{
return(hasLeft( x, y - 1 ) );
}
protected bool hasRightDown( int x, int y )
{
return(hasRight( x, y - 1 ) );
}
/* 测试用 */
protected void test()
{
foreach ( ArrayList arraylist in mapContainer )
{
string output = null;
foreach ( var e in arraylist )
{
output += e;
}
Debug.Log( output );
}
}
public virtual void updateAllTile()
{
}
public virtual void updateAroundTile( int x, int y )
{
}
}
子类,用来更改Sprite与合并碰撞体,为什么要写子类呢?因为我觉得有拐角与没有的可以分开处理。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AutoEdgeTiles : AutoTile
{
/* 序列化不同的图片,也许有资源集之类更好的办法,还望大神能指点一二 */
public Sprite SpriteMid, SpriteLeft, SpriteRight, SpriteUp, SpriteDown,
SpriteUpLeft, SpriteUpRight, SpriteDownLeft, SpriteDownRight, SpriteUpDown, SpriteLeftRight,
SpriteOnlyOne, SpriteOnlyLeft, SpriteOnlyRight, SpriteOnlyUp, SpriteOnlyDown;
void Awake()
{
intinalBasePoint();
updateAllTile();
/*
* 测试用,testX,testY要声明
* test ();
* Debug.Log(hasLeftUp(testX, testY)+"t"+hasUp (testX, testY)+"t"+hasRightUp(testX, testY)+
* "n"+hasLeft(testX, testY)+"tt"+hasRight(testX, testY)+
* "n"+hasLeftDown(testX, testY)+"t"+hasDown(testX, testY)+"t"+hasRightDown(testX, testY));
*/
}
override public void updateAllTile()
{
/* 父类中 */
intinalMapContainer();
/* 遍历每个tile */
foreach ( Transform tra in childrenTransforms )
{
if ( tra.tag == "Tile" )
{
Vector2 pos = tra.position;
int x, y, code = 0;
x = (int) ( (pos.x - basePoint.x) / sideLength + 0.05f);
y = (int) ( (pos.y - basePoint.y) / sideLength + 0.05f);
if ( isCoillder )
changeCoillder2D( tra, x, y );
/*一种类似二进制的判别法
*顺序上左下右
*/
if ( hasUp( x, y ) )
code += 1;
if ( hasDown( x, y ) )
code += 4;
if ( hasLeft( x, y ) )
code += 8;
if ( hasRight( x, y ) )
code += 2;
tra.gameObject.GetComponent ().sprite = findSpriteWithCode( code, tra, x, y );
}
}
}
/* 在可破化地形情况下使用(没写) */
override public void updateAroundTile( int x, int y )
{
}
/* 改变角 */
void changeConer( Transform tra, int x, int y )
{
if ( !hasLeftUp( x, y ) && hasLeft( x, y ) && hasUp( x, y ) )
tra.Find( "conerLeftUp" ).gameObject.SetActive( true );
if ( !hasRightUp( x, y ) && hasRight( x, y ) && hasUp( x, y ) )
tra.Find( "conerRightUp" ).gameObject.SetActive( true );
if ( !hasRightDown( x, y ) && hasRight( x, y ) && hasDown( x, y ) )
tra.Find( "conerRightDown" ).gameObject.SetActive( true );
if ( !hasLeftDown( x, y ) && hasLeft( x, y ) && hasDown( x, y ) )
tra.Find( "conerLeftDown" ).gameObject.SetActive( true );
}
/* 假如是可碰撞体,就想办法合并Collider2D,节省性能并防止“抽搐”问题 */
void changeCoillder2D( Transform tra, int x, int y )
{
if ( hasUp( x, y ) && hasDown( x, y ) && hasLeft( x, y ) && hasRight( x, y ) )
{
tra.GetComponent ().enabled = false;
return;
} else if ( hasLeft( x, y ) )
{
tra.GetComponent ().enabled = false;
return;
} else if ( !hasLeft( x, y ) )
{
BoxCollider2D theBox = tra.GetComponent ();
int count = 1;
while ( hasRight( x + count - 1, y ) )
{
count++;
}
theBox.size = new Vector2( sideLength * count, sideLength );
theBox.offset = new Vector2( sideLength / 2.0f * (count - 1), 0 );
}
return;
}
Sprite findSpriteWithCode( int code, Transform tra, int x, int y )
{
switch ( code )
{
case 0:
return(SpriteOnlyOne);
case 1:
return(SpriteOnlyUp);
case 2:
return(SpriteOnlyRight);
case 3:
changeConer( tra, x, y );
return(SpriteDownLeft);
case 4:
return(SpriteOnlyDown);
case 5:
return(SpriteUpDown);
case 6:
changeConer( tra, x, y );
return(SpriteUpLeft);
case 7:
changeConer( tra, x, y );
return(SpriteLeft);
case 8:
return(SpriteOnlyLeft);
case 9:
changeConer( tra, x, y );
return(SpriteDownRight);
case 10:
return(SpriteLeftRight);
case 11:
changeConer( tra, x, y );
return(SpriteDown);
case 12:
changeConer( tra, x, y );
return(SpriteUpRight);
case 13:
changeConer( tra, x, y );
return(SpriteRight);
case 14:
changeConer( tra, x, y );
return(SpriteUp);
case 15:
changeConer( tra, x, y );
return(SpriteMid);
default:
changeConer( tra, x, y );
return(SpriteMid);
}
}
}
unity 陶瓷质感_Unity2D:简单自动瓷砖(Tile)的实现相关推荐
- unity 陶瓷质感_一种基于Unity3D的虚拟陶瓷设计方法与流程
本发明涉及虚拟现实领域,特别涉及一种基于Unity3D的虚拟陶瓷设计方法. 背景技术: 陶艺工艺制作环境要求严格:不仅在拉坯成型需要利用旋转机器,在烧制过程则需要窑炉锻造,如何将陶瓷制作工艺与虚拟现实 ...
- Unity 工具 之 VText 简单快速实现 文字 3D 效果,VText 的导入设置和简单使用(可支持中文字体)
Unity 工具 之 VText 简单快速实现 文字 3D 效果,VText 的导入设置和简单使用(可支持中文字体) 目录 Unity 工具 之 VText 简单快速实现 文字 3D 效果,VText ...
- 编译原理(简单自动词法分析器LEX)
编译原理(简单自动词法分析器LEX)源程序下载地址: http://files.cnblogs.com/files/hujunzheng/%E6%B1%87%E7%BC%96%E5%8E%9F%E7 ...
- Unity 进阶 之 实现简单的音频可视化封装(包括音频和麦克风)
Unity 进阶 之 实现简单的音频可视化封装(包括音频和麦克 目录 Unity 进阶 之 实现简单的音频可视化封装(包括音频和麦克 一.简单介绍 二.实现原理 三.注意事项 四.效果预览 五.实现步 ...
- Ruby‘s Adventrue游戏制作笔记(十二)Unity给角色添加简单的特效
Ruby's Adventrue游戏制作笔记(十二)Unity给角色添加简单的特效 前言 一.把特效物品进行切割 二.创建 particle System 三.创建彩色球 四.再设置一下其他属性 五. ...
- Vue 之 vue-seamless-scroll 实现简单自动无缝滚动,且添加对应点击事件的简单整理
Vue 之 vue-seamless-scroll 实现简单自动无缝滚动,且添加对应点击事件的简单整理 目录 Vue 之 vue-seamless-scroll 实现简单自动无缝滚动,且添加对应点击事 ...
- Unity入门——实现一个简单的跑酷游戏(资源预制)
Unity入门--实现一个简单的跑酷游戏 资源预制 一款跑酷游戏,需要大量重复的场景资源,比如道路.障碍物等,无论是从游戏体验的角度还是运行效率的角度考虑,都不应该全部事先摆好,而是应该由代码随机生成 ...
- 【Unity3D 灵巧小知识点】 ☀️ | Unity中几个简单又常见的报错异常
Unity 小科普 老规矩,先介绍一下 Unity 的科普小知识: Unity是 实时3D互动内容创作和运营平台 . 包括游戏开发.美术.建筑.汽车设计.影视在内的所有创作者,借助 Unity 将创意 ...
- [Unity3D]用C#在unity里面写一个简单的红绿灯
[Unity3D]用C#在unity里面写一个简单的红绿灯 00.成果展示 01.创建可变颜色的小球 02.编写代码 R1.cs R2.cs G1.cs G2.cs Y1.cs Y2.cs 03.自己 ...
最新文章
- IDEA IntelliJ 如何给web项目配置tomcat
- 设计模式C++实现(13)——中介者模式
- Longest Palindromic Substring
- spring boot jwt_springboot整合JWT
- 「新手向」koa2从起步到填坑
- JAVA常见算法题(四)
- 中缀表达式转后缀表达式(Java)
- 鸿蒙系统硬盘分区,硬盘分区2种格式
- 使用bat注册ocx
- 怎么用计算机测出来体脂,keep软件测体脂率的在哪 keep怎么测体脂
- ISAPI概述(转)
- 用一报还一报(TIT FOR TAT)策略的胜利指导我们的生活和人际交往
- “真功夫”与“花拳绣腿”
- 【中创算力】第六届优秀员工表彰大会暨四月中创生日会
- ps铅笔素描效果教程
- Hash——哈希法概念、哈希函数构造方法、哈希冲突解决办法(重点讨论链地址法)
- CTF MISC系列————8、Misc1-纵横四海
- CVS投中app数据采集
- Java分离中文姓名姓氏和名字
- php去除换行符的方法