Unity3D手机游戏开发的一些笔记
2015-09-02 17:07
603 查看
<span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">发布选项:50页</span></span>
选中Run In Background 即使游戏窗口失去焦点,也会在后台运行.
如果在Display Resolution Dialog中选择Disabled,游戏在每次启动时不会显示一个用于设置显示分辨率的窗口。
;Icon选择组;可以设置不同大小的图标,如果不指定,他们将会自动调用Default Icon中设置的图标并自动缩放。可能会有锯齿
Override for Standalone根据分辨率替换默认图标.
默认启动Unity游戏会看到Unity的商标,在Splash Image中指定一张图片即可.(这个功能只有在pro版本中才能使用)
;Oher Settings选项组。Static Batching是Unity Pro版本功能,它将静态模型整合,但有时会使游戏尺寸变大,如果不清楚优化原理,建议慎重使用这个功能。
;Rendering Path中可以设置3钟渲染模式:
1.Deferred Lighting有最真是的灯光效果,可以不受数量限制地使用灯光和实时阴影,所有的灯光都支持per-pixel(用于计算normal maps),该模式当前不支持抗锯齿和半透明显示。只有unity pro才支持这种模式,需要显卡支持shader model 3.0或更高。不支持手机平台。
2.Forward Rendering以Shader为基础,只能用一个方向光实时阴影。在【Edit】->【Project Settings】->【Quality】,在Pixel Light Count里可以设置per pixel灯光的最大数量。
3.Vertex Lit是灯光效果最简单的渲染模式,不支持实时阴影。不支持normal maps,但有最好的性能,适合在一些较差的硬件上使用。
Navigation寻路简单实用:60页
Gizmos小提示的使用:79页
void OnDrawGizmos() { Gizmos.DrawIcon(transform.position, "item.png", true);//允许缩放 }item.png纹理在Gizmos文件下。
屏幕自动分辨率,只能按高度比例
小地图制作:80页
摄像机的Normalized viewport rect属性
指定如何将摄像机的视图绘制到屏幕坐标系上(取值范围为0-1)
X:摄像机视图在屏幕上被绘制的水平初始位置
Y:摄像机视图在屏幕上被绘制的垂直初始位置
W:摄像机视图输出图像占屏幕宽度的比例
H:摄像机视图输出图像占屏幕高度的比例
U3D屏幕的坐标系是以左下角为坐标原点,向右为X轴,向上为Y轴
原文:http://blog.csdn.net/kfqcome/article/details/10159201
87页:在不基础MonBehaviour的类前面加[System.Serializable]使得变量可以被Inspector界面获得。其二:指示一个类可以序列化(数组?),不能被继承。
91页: 在函数前面添加[ContextMenu("BuildMap")]//上下文菜单,添加它之后,可以在编辑状态下手动执行BuildMap
99页:在Assets目录下创建名为Editor的文件夹,名称是特定的,不能改变,所有需要在编辑状态下执行的脚本都应当存放到这里。
99页:接着上面一条,在函数名称前加[MenuItem("PathTool/Set Parent %q")] 菜单栏里会多出一个PathTool菜单,菜单下有Set Parent选项。快捷键是Ctrl+q。点击会运行这个函数。记得using UnityEditor;
100页:接着上面,这里的代码只有在编辑状态才能被执行,注意PathTool继承自ScriptableObject并在前面引用了UnityEditor。所有在这里使用的属性和函数均为static类型。
106-109页:excel生成xml数据
xml基本格式。必须定义两列table只有这样在Excel中才能批量映射数据元素。
<?xml version="1.0" encoding="uft-8"?> uft-8不支持就改成gb2312 <ROOT> <!-- content --> <table wave="" enemyname="" level="" wait="" /> <table wave="" enemyname="" level="" wait="" /> </ROOT>
</pre><p>111页:用官方精简的XMLParser解析读取XML数据:</p><p></p><pre name="code" class="csharp"> void ReadXML() { enemylist = new ArrayList(); XMLParser xmlparser = new XMLParser();//XML解析器 XMLNode node = xmlparser.Parse(xmldata.text);//开始解析TextAsset XMLNodeList list = node.GetNodeList("ROOT>0>table");//只是看看有几行table for(int i=0;i<list.Count;i++) { //从XML节点里 string wave = node.GetValue("ROOT>0>table" + i + ">@wave");//获取第i行table的wave值 string enemyname = node.GetValue("ROOT>0>table" + i + ">@enemyname"); string level = node.GetValue("ROOT>0>table" + i + ">@level"); string wait = node.GetValue("ROOT>0>table" + i + ">@wait"); SpawnData data = new SpawnData();//保存从xml提取的数据 data.wave = int.Parse(wave); data.enemyname = enemyname; data.level = int.Parse(level); data.wait = int.Parse(wait); enemylist.Add(data);//获取某行的所有数据 } }
117页:RotateTo函数的实现方法。
121页:Mesh和UV的一些应用
第五章:资源创建
134页:Render Mode是一个重要的选项,当设为Important时渲染将达到像素质量,设为Not Important则总是一个顶点光,但可以获得更好的性能。
Culling Mask:选择遮罩可以控制光英雄的对象。
Lightmapping:可设为RealtimeOnly或BackedOnly,这将使光源仅能用于实时照明或烘培Lightmap。默认是Auto
环境光:是unity提供的一种特殊光源,它没有范围和方向的概念,会整体的改变场景亮度。环境光在场景中是一直存在的,在菜单栏选择【Edit】->【Render Settings】 Ambient Light
Fog雾:Fog Density雾的强度。雾功能对性能造成一定影响,在硬件性能较差的平台要谨慎使用这个功能。
135页:lightmapping 烘培?使用灯光贴图的模型必须有第二套UV,这套UV原则上不能有UV重叠的地方。
136页:【Window】->【Lightmapping】打开Lightmapping窗口。选择Build下面的Back Reflection Probes再点Build进行烘培设置。
Bounces:决定光子的计算级别。其他一些属性可以在136-137页看。所有光影贴图都会自动存放在当前场景的存放路径。
isset用来检测该变量是否被设置。
164页:服务器配置
174页:WWW的基本应用
175页:GET请求
176页:POST请求。using System.Collections.Generic;Dictionary
178页:上传下载图片
1、选中图片:Inspector窗口下第一个选项,Texture Type 改成 Advanced;
2、选中Read/Write Enabled。
3、选中下方Override for Standalone,Format这图片ARGB 32bit
180页:下载声音文件
224页:对象序列化于反序列化简单演示
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using System.Runtime.Serialization.Formatters.Binary; // 运行时刻 序列化 格式化 二进制 namespace ConsoleApplication1 { [Serializable]//序列化是将对象状态转换为可保持或传输的格式的过程。 public class Player { public int id; public string name; public int life; } class Program { static void Main(string[] args) { Player player = new Player(); player.id = 1; player.name = "hero"; player.life = 1000; using(MemoryStream stream =new MemoryStream())//创建存储区为内存的流 IO { //创建序列化类 BinaryFormatter bf = new BinaryFormatter();//以二进制格式将对象或整个连接对象图形序列化和反序列化。 bf.Serialize(stream, player);//将对象(或具有指定顶级(根)的对象图形)序列化给指定流 //bf将player对象序列化到stream内存流中。 stream.Seek(0, SeekOrigin.Begin);//将流中的位置设成,开始!? Player player2; player2 = (Player)bf.Deserialize(stream);//将stream保存的数据反序列化。然后转化成Player类对象 Console.WriteLine("{0},{1},{2}", player.id, player2.name, player2.life); } } } }
225页:简单的Server和Client连接发送接收数据
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net; using System.Net.Sockets;//套接字 namespace SimpleServer { class Program { static void Main(string[] args) { string ip = "127.0.0.1"; //端口 int port = 8000; try { //获得终端地址 IPEndPoint ipe = new IPEndPoint(IPAddress.Parse(ip), 8000);//本机地址 //创建socket Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 监听 地址族-ip4版本地址 套接字类型-双向连接的字节流 协议类型-Tcp listener.Bind(ipe);//相对 - 开始连接 //开始监听 最大允许处理1000个连接 listener.Listen(1000);//开始监听 Console.WriteLine("开始监听"); //开始接受客户端请求 程序在这里会阻住 Socket mySocket = listener.Accept();//接受一个连接。将这个"连接socket"返回。保存在mySocket byte[] bs = new byte[1024]; int n = mySocket.Receive(bs);//将接受的数据存入缓存区bs //在等待另一个连接 发送数据 Console.WriteLine(n.ToString()); mySocket.Send(bs);//发送数据。到连接的Socket mySocket.Close(); } catch(Exception e) { Console.WriteLine(e.Message); } } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net; using System.Net.Sockets; namespace SimpleClient { class Program { static void Main(string[] args) { //服务器ip地址 string ip = "127.0.0.1"; //服务器端口 int port = 8000; try { //获得终端 IPEndPoint ipe = new IPEndPoint(IPAddress.Parse(ip), port); Socket client = new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp); //开始连接服务器,程序会在这里阻住,直到连接成功或失败 client.Connect(ipe); Console.WriteLine("连接到服务器"); //向服务器发送数据 string data = "hello world"; byte[] bs = UTF8Encoding.UTF8.GetBytes(data);//字符串转化到字节集 client.Send(bs); byte[] rev = new byte[256]; //接受到服务器返回的数据 client.Receive(rev);//在等待另一个连接 发送数据 Console.WriteLine(UTF8Encoding.UTF8.GetString(rev)); client.Close(); } catch(Exception e) { Console.WriteLine(e.Message); } } } }
编译c#成dll放到unity中使用时,要将net framework版本至少设成3.5。class权限也要是public
251页:
protogen -i:chatapp.proto -o:chatapp.cs
package ChatAPP;//命名空间 message User {//类 required string name=1;//123好像只是第几变量 required string chat=2;//required必须的变量 optional string email=3;//可选的变量 } message Chat{ repeated User user = 1;//多个User变量(数组?) }
335页:设置Android游戏工程
342页:触屏API
<pre name="code" class="csharp">public class AndroidTouch : MonoBehaviour { Vector2 m_screenpos = new Vector2(); float m_speed = 0.1f; // Use this for initialization void Start() { //Debug.Log(Input.multiTouchEnabled); Input.multiTouchEnabled = true;//设置多点触屏 } // Update is called once per frame void Update() { if (Input.GetKeyUp(KeyCode.Escape)) Application.Quit(); #if !UNITY_EDITOR && (UNITY_IOS || UNITY_ANDROID)//判断是编辑(pc)平台还是移动手机平台 MobileInput(); #else DesktopInput(); #endif } void DesktopInput() { //记录鼠标左键的移动距离 float mx=Input.GetAxis("Mouse X"); float my=Input.GetAxis("Mouse Y"); if(mx!=0 || my!=0) { //鼠标左键 if(Input.GetMouseButton(0)) { Camera.main.transform.Translate(new Vector3(mx,my,0)); } } } //滑动输入 void MobileInput() { if (Input.touchCount < 0) return; if (Input.touchCount == 1) { //开始触屏 if (Input.touches[0].phase == TouchPhase.Began)//触屏阶段==开始 { //记录手指触屏的位置 m_screenpos = Input.touches[0].position; } else if (Input.touches[0].phase == TouchPhase.Moved) //手指移动 { //移动摄像机 Camera.main.transform.Translate(new Vector3(Input.touches[0].deltaPosition.x * m_speed, Input.touches[0].deltaPosition.y * m_speed, 0)); //deltaPosition增量值 } //手指离开屏幕后 if (Input.touches[0].phase == TouchPhase.Ended && Input.touches[0].phase != TouchPhase.Canceled) //系统取消跟踪触摸,如用户把屏幕放到他脸上或超过五个接触同时发生。这是一个触摸的最后状态 { Vector2 pos = Input.touches[0].position;//离开位置 //手指水平移动(多点) if (Mathf.Abs(m_screenpos.x - pos.x) > Mathf.Abs(m_screenpos.y - pos.y)) { if (m_screenpos.x > pos.x) { //开始点.x大于结束点.x 手指向左滑动 } else { //否则 向右滑动 } } else //手指垂直移动 { if (m_screenpos.y > pos.y) { //开始点.y大于结束点.y 手指向下滑动(Y上小,下大) } else { //否则向上滑动 } } } } else if(Input.touchCount>1) { //记录两个手指的位置 Vector2 finger1 = new Vector2(); Vector2 finger2 = new Vector2(); //记录两个手指的移动距离 Vector2 mov1 = new Vector2(); Vector2 mov2 = new Vector2(); for(int i=0;i<2;i++) { Touch touch = Input.touches[i]; if (touch.phase == TouchPhase.Ended) break; //如果手指处于移动状态 if(touch.phase==TouchPhase.Moved) { float mov = 0; if(i==0) { //获得手指1的位置和移动 finger1 = touch.position; mov1 = touch.deltaPosition;//移动量 } else { //获得手指2的位置和移动 finger2 = touch.position; mov2 = touch.deltaPosition; //获得手指移动距离 if(finger1.x>finger2.x)//获取最右边手指的增量 { mov = mov1.x; } else { mov = mov2.x; } if(finger1.y>finger2.y)//获取下面那根手指的增量 { mov += mov1.y; }else { mov += mov2.y; } //根据手指移动距离改变摄像机位置 Camera.main.transform.Translate(0, 0, mov * m_speed); } } } } } }
348页:java代码
F:\unity5.3.2f1\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Development\Classes
package com.testc.test; import android.os.Bundle; import android.app.Activity; import android.app.AlertDialog; import com.unity3d.player.UnityPlayer; import com.unity3d.player.UnityPlayerActivity; //mainActivitty继承自UnittyPlayerActtivitty public class MainActivity extends UnityPlayerActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } //准备在unity中调用的参数,有两个参数 protected void HelloWorld(final String title,final String content) { runOnUiThread(new Runnable() { public void run() { MakeDialog(title,content); } }); } //显示对话框 public void MakeDialog(String title,String content) { AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); builder.setTitle(title) .setMessage(content) .setCancelable(false) .setPositiveButton("OK", null); builder.show(); } }
349页:Clean出现一些问题。
建立project时Theme改为none。还有main什么的把值直接删掉
另外:AndroidManifest.xml在F:\unity5.3.2f1\Editor\Data\PlaybackEngines\AndroidPlayer\Apk
AndroidMainfest.xml文件改:包+类名
<activity android:name="com.testc.test.MainActivity"
<img src="http://img.blog.csdn.net/20160201171143083?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
350页:
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
351页:在Eclipse查看Log
355页:设置导出的eclipse工程:
一些库要把鼠标放在出错那里,点导入XX库!函数放在最高基类或继承,如:UnityPlayerActivity这个类
另外可以选择:
UnityPlayerNativeActivity extends UnityPlayerActivity
JAVA:
protected void HelloWorld(final String title,final String content) { runOnUiThread(new Runnable(){ public void run(){ MakeDialog(title,content); } }); } //显示对话框 public void MakeDialog(String title,String content) { AlertDialog.Builder builder= new AlertDialog.Builder(UnityPlayerNativeActivity.this); builder.setTitle(title) .setMessage(content) .setCancelable(false) .setPositiveButton("OK", new DialogInterface.OnClickListener(){ public void onClick(DialogInterface dialog,int which){ UnityPlayer.UnitySendMessage("AndroidManager","AndroidCallback",""); }}); builder.show(); }
c#:
try { string[] args = new string[2]; args[0] = "Hello"; args[1] = "World"; Debug.Log(active.ToString()); // active.Call("MakeDialog", args); active.Call("HelloWorld");//被调用的函数名+参数数组 Debug.Log("完成调用!"); } catch(System.Exception ex) { Debug.Log(ex.Message); }运行方式:项目右键 Run-As ->AndroidApplicattion。然后 就可以run了。
355页:
android:debuggable="false"有问题可以删掉或改
相关文章推荐
- unity开发相关环境(vs、MonoDevelop)windows平台编码问题
- unity制作一个3d旋转菜单
- Unity出现 error building player exception android (invocation failed)
- Unity 2D游戏开发教程之使用脚本实现游戏逻辑
- Unity3d项目工程批量打包
- Unity 2D游戏开发教程之使用脚本实现游戏逻辑
- Unity3d使用RenderTexture制作动态头像
- unity新版动画系统个人心得
- Unity3D自己常用代码
- Unity3D自己常用代码
- unity3d 单例模式
- Unity3D学习笔记《Space Shooter》一
- Unity3d碰撞器与触发器的区别详解(rigidbody移动和charactercontroller移动区别)
- Unity5内部渲染的优化1:介绍
- Unity Sprite Packer 使用指南
- Unity屏幕震动实现(通过Camera Viewpoint)
- unity3d中脚本生命周期(MonoBehaviour lifecycle)
- 关于unity中的update、Lateupdate和FixedUpdate。
- C# Memory Management for Unity Developers (part 3 of 3)
- C#Memory Management for Unity Developers (part 2 of 3)