1.AssetDatabase的使用:
此类是Project面板的文件管理类(使用AssetDatabase. LoadAssetAtPath(path,typeof(GameObject))在iOS将读取不到文件)。
2.动态读取模型或贴图:
首先要将模型和贴图放入Resources文件夹中,可以有子文件夹(读取时注意路径),然后用Resources.Load(path,typeof(GameObject))读取(读取时的文件名不要加后缀,否则读取不到),不要使用LoadAssetAtPath(path,typeof(GameObject))方法,此方法无效。
3.unity3d中加入背景:
其实就是加入天空盒到相机上,加入天空盒之前必须导入天空盒Asset->Import Package->Skyboxes。
4.unity3d之IOS Document:
很多unity开发者比较纠结IOS document操作,本文将以读取document下的图片为例,实现Document文件操作扫盲教程,此篇为上一篇续集,document下的图片是拍照完成后保存的。保存图片到document操作如下:
-(void)SavePngToDocument:(UIImage*)img{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *savedImagePath = [documentsDirectory stringByAppendingPathComponent:@"pic.png"];
NSData *imageData = UIImagePNGRepresentation(img);
[imageData writeToFile:savedImagePath atomically:NO];
}
unity3d中通过如下操作获取Document文件路径
public string JsonPath
{
get{
string path=null;
if(Application.platform==RuntimePlatform.IPhonePlayer)
{
path= Application.dataPath.Substring (0, Application.dataPath.Length - 5);
path = path.Substring(0, path.LastIndexOf('/'))+"/Documents/";
}
else
{
path=Application.dataPath+"/Resource/GameData/";
}
return path;
}
}
通过WWW加载图片
IEnumerator InstanceTexture(string fileName)
{如果为网上材料则用“http://”
string path="file://"+JsonPath+fileName;
print(path);
WWW wwwTexture=new WWW(path);
yield return wwwTexture;
print(wwwTexture.texture.name);
}
5.unity3d之IEnumerator问题:
public IEnumerator ControllAnimation()
{
if (Input.GetKey(KeyCode.A)&& animation .isPlaying )
{
Debug.Log(3333333333333);
animation.Play("tengkongsi", PlayMode.StopAll);
//等待动画播放完成
yield return new WaitForSeconds (animation["tengkongsi"].length);
}
}
上面那段代码我是用C#写的,可为什么添加上最后一句代码,返回类型变成IEnumerator 之后,该方法在程序中就调不到了呢?
答:你这的ControllAnimation现在是协同函数了
要用StartCoroutine来调用
StartCoroutine(ControllAnimation());
更详细的用法查用户手册
6.unity3d之struct byte[] 与 Object互转(好像没有用):
public static byte[] StrutsToBytesArray(object structObj)
- {
- //得到结构体的大小
- int size = Marshal.SizeOf(structObj);
- //创建byte数组
- byte[] bytes = new byte[size];
- //分配结构体大小的内存空间
- IntPtr structPtr = Marshal.AllocHGlobal(size);
- //将结构体拷到分配好的内存空间
- Marshal.StructureToPtr(structObj, structPtr, false);
- //从内存空间拷到byte数组
- Marshal.Copy(structPtr, bytes, 0, size);
- //释放内存空间
- Marshal.FreeHGlobal(structPtr);
- //返回byte数组
- return bytes;
- }
- public static object BytesToStruts(byte[] bytes, Type type)
- {
- //得到结构体的大小
- int size = Marshal.SizeOf(type);
- //byte数组长度小于结构体的大小
- if (size > bytes.Length)
- {
- //返回空
- return null;
- }
- //分配结构体大小的内存空间
- IntPtr structPtr = Marshal.AllocHGlobal(size);
- //将byte数组拷到分配好的内存空间
- Marshal.Copy(bytes, 0, structPtr, size);
- //将内存空间转换为目标结构体
- object obj = Marshal.PtrToStructure(structPtr, type);
- //释放内存空间
- Marshal.FreeHGlobal(structPtr);
- //返回结构体
- return obj;
- }
-
7.unity3d将一张图片做成全景图:
你说的应该是skybox 你把那个图片平均的切成9块儿 然后unity里创建Cubemap 吧图片接上去就可以了
8.unity3d选中某物体:
Ray ray = mCamera.ScreenPointToRay (new Vector3 (touch.position.x, touch.position.y,0));
RaycastHit[] hits;
hits = Physics.RaycastAll (ray, 50);
似乎这个的检测是离屏幕最远的第一个检测出来,打出的log似乎是这样的
9.unity3d处理用户按下iPhone上的home键:
func OnAppQuit(){}
10.unity3d中让gameobject隐藏/显示的方法:
gameObject.renderer.enabled = false; 或者
gameObject.active = false;
1.首先贴图的wrap mode需要设置为repeat
2.将tiling设置为>1的数值,具体的数值根据贴图的大小以及模型的大小进行设置
11.unity3d导入fbx模型(贴图和材质球名字一样,贴图将会自动载入,烘培贴图必须手动导入):
在FBX导出选项中,把“嵌入的媒体”一项打上勾,FBX文件格式的类型,选择“二进制”。这样的FBX在unity中就能看到贴图了。可能某些方式的贴图只有3DMAX格式本身支持,FBX还会不支持。
问题:
从3dsMax导出fbx给Unity用,总是会丢失贴图。尽管Unity导入fbx时会自动导入材质球,但是贴图文件都会变成空的,要重新一个一个贴图填进去,真是太浪费时间了。
解决方案:
3dsMax中模型和贴图采用统一命名,贴图文件拷贝到Unity项目中,然后再导入fbx,就会为自动创建的材质找到对应贴图了。
先放贴图再放fbx,路径不要有中文,贴图都放在一个文件夹下和fbx文件,不能文件夹套文件夹
12.xcode中截取EAGLView,从unity3d中导出iOS项目时,抗锯齿不要选择good或更高级别,这样会截图失败(根本原因是因为Anti Aliasing没有选择disabled)
//delegate协议方法,截取unity图,不能用通常的截图
- (UIImage *) clipPicture
{
GLint backingWidth, backingHeight;
// Bind the color renderbuffer used to render the OpenGL ES view
// If your application only creates a single color renderbuffer which is already bound at this point,
// this call is redundant, but it is needed if you're dealing with multiple renderbuffers.
// Note, replace "_colorRenderbuffer" with the actual name of the renderbuffer object defined in your class.
//glBindRenderbufferOES(GL_RENDERBUFFER_OES, _colorRenderbuffer);
// Get the size of the backing CAEAGLLayer
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
NSInteger x = 0, y = 0, width = backingWidth, height = backingHeight;
NSInteger dataLength = width * height * 4;
GLubyte *data = (GLubyte*)malloc(dataLength * sizeof(GLubyte));
// Read pixel data from the framebuffer
glPixelStorei(GL_PACK_ALIGNMENT, 4);
glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);
// Create a CGImage with the pixel data
// If your OpenGL ES content is opaque, use kCGImageAlphaNoneSkipLast to ignore the alpha channel
// otherwise, use kCGImageAlphaPremultipliedLast
CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, data, dataLength, NULL);
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGImageRef iref = CGImageCreate(width, height, 8, 32, width * 4, colorspace, kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast,
ref, NULL, true, kCGRenderingIntentDefault);
// OpenGL ES measures data in PIXELS
// Create a graphics context with the target size measured in POINTS
NSInteger widthInPoints, heightInPoints;
if (NULL != UIGraphicsBeginImageContextWithOptions) {
// On iOS 4 and later, use UIGraphicsBeginImageContextWithOptions to take the scale into consideration
// Set the scale parameter to your OpenGL ES view's contentScaleFactor
// so that you get a high-resolution snapshot when its value is greater than 1.0
CGFloat scale = _window.contentScaleFactor;
widthInPoints = width / scale;
heightInPoints = height / scale;
// widthInPoints = width ;
// heightInPoints = height;
UIGraphicsBeginImageContextWithOptions(CGSizeMake(widthInPoints, heightInPoints), NO, scale);
}
else {
// On iOS prior to 4, fall back to use UIGraphicsBeginImageContext
widthInPoints = width;
heightInPoints = height;
UIGraphicsBeginImageContext(CGSizeMake(widthInPoints, heightInPoints));
}
CGContextRef cgcontext = UIGraphicsGetCurrentContext();
// UIKit coordinate system is upside down to GL/Quartz coordinate system
// Flip the CGImage by rendering it to the flipped bitmap context
// The size of the destination area is measured in POINTS
CGContextSetBlendMode(cgcontext, kCGBlendModeCopy);
CGContextDrawImage(cgcontext, CGRectMake(0.0, 0.0, widthInPoints, heightInPoints), iref);
#define kIsPad 1
CGSize size = kIsPad ? CGSizeMake(140, 44) : CGSizeMake(70, 22);
CGRect rect={{widthInPoints-size.width, heightInPoints-size.height-(kIsPad ? 70 : 48)}, size};
UIImage *logoMark = [UIImage imageNamed:@"pic.png"];
[logoMark drawInRect:rect];
// Retrieve the UIImage from the current context
UIImage* clipUnity = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Clean up
free(data);
CFRelease(ref);
CFRelease(colorspace);
CGImageRelease(iref);
// [self SavePngToDocument:image1];//保存图片到Document
return clipUnity;
}
//结束
12.unity中截图,抗锯齿不要选择good或更高级别,这样会截图失败(根本原因是因为Anti Aliasing没有选择disabled),当设置了抗锯齿后,只能在unity中用Application.CaptureScreenshot("Screenshot.png");路径为string savePath = Application.persistentDataPath+"/Screenshot.png";
1.Application.CaptureScreenshot("Screenshot.png");这张Screenshot.png图片被存在了当前工程的子目录下了。之前在android上面一直不知道路径,后来把所有路径试玩了总算ok了,呵呵~~~在android上截取的图片存在Application.persistentDataPath上面,在pc上存在Application.dataPath
2.
Texture2D clipTex = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
//隸サ蜿睦ect蛹コ蝓溽噪蜒冗エ
clipTex.ReadPixels(new Rect(0 , 0, Screen.width, Screen.height), 0, 0);
clipTex.Apply();
//霓ャ荳コbytes謨ー扈
byte[] bytes = clipTex.EncodeToPNG();
Destroy(clipTex);
var cache = new FileStream(savePath, FileMode.Create);
cache.Write(bytes, 0, bytes.Length);
cache.Close();
13.动态设置抗锯齿脚本
- using UnityEngine;
- using System.Collections;
- public class AA_Picker : MonoBehaviour {
- public int iPhone_ = 0;
- public int iPhone3G_ = 0;
- public int iPhone3GS_ = 0;
- public int iPhone4_ = 0;
- public int iPhone4S_ = 2;
- public int iPhone5_ = 8;
- public int iPodTouch1Gen_ = 0;
- public int iPodTouch2Gen_ = 0;
- public int iPodTouch3Gen_ = 0;
- public int iPodTouch4Gen_ = 0;
- public int iPodTouch5Gen_ = 4;
- public int iPad1Gen_ = 0;
- public int iPad2Gen_ = 4;
- public int iPad3Gen_ = 2;
- public int Unknown_;
- public int AALevel;
- void Awake(){
- DontDestroyOnLoad(transform.gameObject);
- SetAA();
- }
- void SetAA(){
- #if UNITY_IPHONE
- if(Application.platform == RuntimePlatform.IPhonePlayer){
- if( iPhone.generation == iPhoneGeneration.iPhone)
- {
- AALevel = iPhone_;
- }
- else if( iPhoneSettings.generation == iPhoneGeneration.iPhone3G)
- {
- AALevel = iPhone3G_;
- }
- else if( iPhoneSettings.generation == iPhoneGeneration.iPhone3GS)
- {
- AALevel = iPhone3GS_;
- }
- else if( iPhoneSettings.generation == iPhoneGeneration.iPhone4)
- {
- AALevel = iPhone4_;
- }
- else if( iPhoneSettings.generation == iPhoneGeneration.iPhone4S)
- {
- AALevel = iPhone4S_;
- }
- else if( iPhoneSettings.generation == iPhoneGeneration.iPhone5)
- {
- AALevel = iPhone5_;
- }
- else if( iPhoneSettings.generation == iPhoneGeneration.iPodTouch1Gen)
- {
- AALevel = iPodTouch1Gen_;
- }
- else if( iPhoneSettings.generation == iPhoneGeneration.iPodTouch2Gen)
- {
- AALevel = iPodTouch2Gen_;
- }
- else if( iPhoneSettings.generation == iPhoneGeneration.iPodTouch3Gen)
- {
- AALevel = iPodTouch3Gen_;
- }
- else if( iPhoneSettings.generation == iPhoneGeneration.iPodTouch4Gen)
- {
- AALevel = iPodTouch4Gen_;
- }
- else if( iPhoneSettings.generation == iPhoneGeneration.iPad1Gen)
- {
- AALevel = iPad1Gen_;
- }
- else if( iPhoneSettings.generation == iPhoneGeneration.iPad2Gen)
- {
- AALevel = iPad2Gen_;
- }
- else if( iPhoneSettings.generation == iPhoneGeneration.iPad3Gen)
- {
- AALevel = iPad3Gen_;
- }
- else if( iPhoneSettings.generation == iPhoneGeneration.iPadUnknown)
- {
- AALevel = iPad2Gen_;
- }
- else
- {
- AALevel = Unknown_;
- }
- }else{
- AALevel = Unknown_;
- }
- #endif
- QualitySettings.antiAliasing = AALevel;
- }
- void OnLevelWasLoaded(){
- SetAA();
- }
- }
-
14.xcode中调用unity中的函数,unity不能有重载函数,不然调用时它将随便调用一个。比如void ClipPic()和void ClipPic(string savePath)
15.unity导出iOS如果出现贴图模糊条带问题,在导出的时候打开Player Setting… ,在Resolution and Presentation中勾选Use 32-bit Display Buffer选项。
、
16.unity导出iOS项目,iOS调用unity中的方法,unity的方法不用声明为public的;但如果unity类之间相互调用,则要声明为public。
17.由Matrix4x4得到Quaternion对象
1.听说没用
public static Quaternion QuaternionFromMatrix(Matrix4x4 m) {
// Adapted from: http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
Quaternion q = new Quaternion();
q.w = Mathf.Sqrt( Mathf.Max( 0, 1 + m[0,0] + m[1,1] + m[2,2] ) ) / 2;
q.x = Mathf.Sqrt( Mathf.Max( 0, 1 + m[0,0] - m[1,1] - m[2,2] ) ) / 2;
q.y = Mathf.Sqrt( Mathf.Max( 0, 1 - m[0,0] + m[1,1] - m[2,2] ) ) / 2;
q.z = Mathf.Sqrt( Mathf.Max( 0, 1 - m[0,0] - m[1,1] + m[2,2] ) ) / 2;
q.x *= Mathf.Sign( q.x * ( m[2,1] - m[1,2] ) );
q.y *= Mathf.Sign( q.y * ( m[0,2] - m[2,0] ) );
q.z *= Mathf.Sign( q.z * ( m[1,0] - m[0,1] ) );
return q;
}
2.听说有用
public static Quaternion QuaternionFromMatrix(Matrix4x4 m) { return Quaternion.LookRotation(m.GetColumn(2), m.GetColumn(1)); }
18.世界坐标(global)和本地坐标(local)的转化
1.向量
transform.TransformDirection(GetComponent<MeshFilter>().sharedMesh.normals[0].normalized);//括号里的为mesh网格的法向量
function InverseTransformDirection (direction : Vector3) : Vector3
2.坐标
function TransformPoint (position : Vector3) : Vector3
function InverseTransformPoint (x : float, y : float, z : float) : Vector3
19.当材质用Matrix4x4作旋转matrix [_Rotation]时,则旋转的贴图的scale属性(即tiling属性)将无效,因为改变matrix将会把scale属性也改变,这时要调整scale属性,就必须去改变matrix
Quaternion rotation = Quaternion.Euler(0, 0, rotate);
Vector3 scale = new Vector3(scaleX, scaleY, 1);
Matrix4x4 matRotate = Matrix4x4.TRS(Vector3.zero, rotation, scale);//new Vector3(1, 1, 1));
render.material.SetMatrix("_Rotation",matRotate);