2014-08-29 16:16:27 lihuozhiling 阅读数 3423
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

ok,今天开始接触正式的代码了,几万行的代码,直接就晕了,不知道什么时候才能熟悉过来。大哭

按照自己的经验,熟悉代码方式,最好不过debug了

和eclipse不同的是 Unity 和编代码的MonoDevelop是两个软件,着实让我的脑细胞有点转不过来(固化思维)。

First,如何Debug。

打开Unity,菜单栏 unity-》Preferences->External Tools 第一项External Script tool 确认是Mono


第二步,在unity中打开Mono 菜单栏->Assets->Sync MonoDevelop ok,打开就算加载了当前的解决方案

第三步,先关闭unity 在Mono中设置断点,之后运行-》Run With -> Unity Debugger


ok,Mono会让你再次打开Unity选择工程,打开合适的场景,点击运行,OK,你就会发现,可以进行Debug了。


关于MonoDevelop中无法输入中文的bug,我搜了很久貌似没有解决方案,只有一种就是用Xamarin Studio

我给下载地址http://xamarin.com/download/

安装完毕之后,貌似还需要装MonoFramework-MDK-3.6.0.macos10.xamarin.x86.pkg这个东西

再给链接

http://download.mono-project.com/archive/3.6.0/macos-10-x86/MonoFramework-MDK-3.6.0.macos10.xamarin.x86.pkg

ok,不过它好像没法debug,我去,我再试试把。






2017-04-10 01:55:17 Mogoson 阅读数 911
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

Script Template Toolkit

概述

Unity3D 脚本模板快速编辑,保存。脚本文件添加头注释,自动标注创建日期以及版权时间。

问题

  • 在使用Unity3D创建脚本文件时,希望Unity3D编辑器自动按照个人喜好预定义的模板来创建各类脚本文件,例如添加文件头注释等需求。
  • 希望在脚本头注释中自动标注脚本创建日期,以及根据创建日期标注版权时间(例如:2017-2018)。

条件

  • 实际上,Unity3D将各类脚本文件模板放在了安装目录下(例如:Unity 5.4.1f1\Editor\Data\Resources\ScriptTemplates)。
  • 在Unity3D提供的API中,可以通过AssetModificationProcessor类的OnWillCreateAsset方法捕获Unity3D编辑器创建Asset(包括脚本文件)事件。

方案

编辑

  • 编写Unity3D扩展编辑器代码,通过继承EditorWindow绘制自定义编辑器窗口来编辑/保存Unity3D的各类脚本文件模板(文本文件)。
  • 预定义标注字符串,“#CREATETIME#”标注创建日 期,
    “#COPYRIGHTTIME#”标注版权时间声明,在编辑模板时,在需要插入创建日期的地方使用“#CREATETIME#”标注即可,插入版权时间同理。
  • 使用预定义标注字符串编辑个人喜好风格的脚本文件模板。

创建

  • 在Unity3D编辑器的Project面板通过鼠标右键菜单创建脚本文件(例如:C#)时,Unity3D引擎会将相应的模板文件里边的内容全部拷贝到新建的文件中,且自动将“#SCRIPTNAME#”替换为新建文件时输入的文件名。但是,“#CREATETIME#”,“#COPYRIGHTTIME#”是我们自定义的标注字符串,Unity3D引擎不会识别,也不会将其替换成我们预期的内容。
  • 编写扩展编辑器代码,继承AssetModificationProcessor类并实现其OnWillCreateAsset(string assetPath)方法以捕获Unity3D编辑器创建Asset(包括脚本文件)事件以及处理我们自定义的标注字符串。
  • 捕获到创建Asset事件,检查文件扩展名,如果是.cs或.js或.shader或.compute则说明创建的是脚本文件,也就是说Unity3D引擎会按照相应的模板(例如C#,我们之前已经将其编辑成个人喜好风格的文本)来创建。(扩展编辑器代码)读取新建文件的内容,将
    “#CREATETIME#”替换成当前日期,将“#COPYRIGHTTIME#”替换成当前年份-下个年份。

实现

扩展编辑器

  • ScriptTemplateEditor.cs 读取/编辑/保存 Unity3D各类脚本模板文件。
  • ScriptTemplateModifier.cs 捕获创建事件,替换预定义标注字符串为其具体含义的内容。

脚本模板示例

  • Template 文件夹下存放各类脚本模板文件的示例,以供读者编写自己风格的模板时参考。

源码

源码托管地址

2012-10-30 08:22:14 asd237241291 阅读数 3672
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

原创文章如需转载请注明:转载自 脱莫柔Unity3D学习之旅 本文链接地址:Unity3D 脚本入门


打印信息 HelloWorld

void Start(){
	//单纯的控制台输出命令,下面两种语法是一样的作用。 (中文注释后一定要英文或者空格结尾)  
	Debug.Log("Hello world");
	print("Hello world,too");
	

	// Debug.Log的一个变体,是用来记录一个错误消息到控制台。如果你想知道在那个对象上发生了错误,这是非常有用的。
	Transform OtherGameobject;
	if(OtherGameobject == null)
		Debug.logError("memberVariable must be set to point to a Transform.", transform);
}



GameObject  :

1. active标识物体是否处于活动状况,若是为非活动状况

2. 对象有Tag标签,可以按照标签查找对象“FindWithTag()”,也可以按照名字查找"find("name")"。

3. 通过主菜单“”选择或者脚本中调用“AddComponent()” 可以给游戏对象添加组件。

4.可以把空的“GameObject”对象当成文件夹来使用,简历明确的层级关系。

ComPonent:

1. 组件是游戏功能的零件,可以接洽关系到Gameobejct对象上为对象添加该组件的功能。

2. Transform是GameObject最基础的组件。

3.脚本是组件的子类型,获得某脚本 OtherScript o = getComponent< OtherScript >()。

MonoBehaviour :

1. 所有脚本持续自MonoBehaviour。脚本可以算作是自定义的一个组件。可以将public类型的属性在检视面板(Inspector)中修改,修改后并不影响脚本内设定的初始值。

2.生命周期:Mono行为

执行顺序:


OnUpdate刷新。
LateUpdate Update之后被调用。
FixedUpdate 基于物理行为,每个物理时间被调用一次。
OnGUI 渲染处理GUI事件。
Reset 重置默认行为时被调用。
OnDisable 当前对象不可用或非激活状态时被调用。
Ondestory 被销毁时被调用。

OnTriggerEnter进入触发器
OnTriggerExit 退出触发器
OnTriggerStay 逗留触发器

OnCollisionEnter进入碰撞
OnCollisionExit 退出碰撞
OnCollisionStay 逗留碰撞

2019-03-04 09:19:39 qq_32141141 阅读数 56
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

Unity3d 调用IOS相册

最近在做项目的时候需要调用IOS相册,作为IOS小白的我也试了下,中间也遇到一些坑,最后还是弄好打包真机测试成功,虽然做出来很快,但是要真的弄清Ios和Unity3d的互通消息机制还是需要慢慢摸索的。

软件环境

 1.Unity3d 2018.3.0f2
 2.Xcode10.1

.h/ .m文件编写

在U3d Assets下面的Plugins\IOS下面创建IOSCameraController.h 和IOSCameraController.m文件。创建可以先创建文本然后更改后缀名。
IOSCameraController.h文件

 //import 引用头文件 相当远Using 
#import<QuartzCore/CADisplayLink.h>
//声明一个IOSCameraController类  继承自UIViewController <>里面是是协议/代理的调用声明 可以理解为c#的接口
@interface IOSCameraController : UIViewController<UIImagePickerControllerDelegate,UINavigationControllerDelegate>
@end

IOSCameraController.m文件

#import "IOSCameraController.h"
@implementation IOSCameraController
-(void)OpenTarget:(UIImagePickerControllerSourceType)type{
   //创建UIImagePickerController实例
   UIImagePickerController *picker;
   picker= [[UIImagePickerController alloc]init];
   //设置代理
   picker.delegate = self;
   //是否允许编辑 (默认为NO)
   picker.allowsEditing = YES;
   //设置照片的来源
   // UIImagePickerControllerSourceTypePhotoLibrary,      // 来自图库
   // UIImagePickerControllerSourceTypeCamera,            // 来自相机
   // UIImagePickerControllerSourceTypeSavedPhotosAlbum   // 来自相册
   picker.sourceType = type;
   
   //这里需要判断设备是iphone还是ipad  如果使用的是iphone并没有问题 但是如果 是在ipad上调用相册获取图片 会出现没有确定(选择)的按钮 所以这里判断
   //了一下设备,针对ipad 使用另一种方法 但是这种方法是弹出一个界面 并不是覆盖整个界面 需要改进 试过另一种方式 重写一个相册界面 
   //(QQ的ipad选择头像的界面 就使用了这种方式 但是这里我们先不讲 (因为我也不太懂 但是我按照简书的一位老哥的文章写出来了 这里放一下这个简书的链接
   //https://www.jianshu.com/p/0ddf4f7476aa)
   if (picker.sourceType == UIImagePickerControllerSourceTypePhotoLibrary &&[[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
       // 设置弹出的控制器的显示样式
       picker.modalPresentationStyle = UIModalPresentationPopover;
       //获取这个弹出控制器
       UIPopoverPresentationController *popover = picker.popoverPresentationController;
       //设置代理
       popover.delegate = self;
       //下面两个属性设置弹出位置
       popover.sourceRect = CGRectMake(0, 0, 0, 0);
       popover.sourceView = self.view;
       //设置箭头的位置
       popover.permittedArrowDirections = UIPopoverArrowDirectionAny;
       //展示选取照片控制器
       [self presentViewController:picker animated:YES completion:nil];
   } else {
       //展示选取照片控制器
       [self presentViewController:picker animated:YES completion:^{}];
   }
  
}
//选择完成,点击界面中的某个图片或者选择(Choose)按钮时触发
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
   //关闭界面
   [picker dismissViewControllerAnimated:YES completion:^{}];
   //得到照片
   UIImage *image = [info objectForKey:@"UIImagePickerControllerEditedImage"];
   if (image == nil) {
       image = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
   }
   //有些时候我们拍照后经常发现导出的照片方向会有问题,要么横着,要么颠倒着,需要旋转才适合观看。但是在ios设备上是正常的
   //所以在这里处理了图片  让他旋转成我们需要的
   if (image.imageOrientation != UIImageOrientationUp) {
   //图片旋转
       image = [self fixOrientation:image];
   }
   //获取保存图片的地址
   NSString *imagePath = [self GetSavePath:@"Temp.jpg"];
   //保存图片到沙盒路径 对应unity中的Application.persistentDataPath 之后我们取图片就需要在这个路径下取  这是一个可读可写的路径
   [self SaveFileToDoc:image path:imagePath];
}
//获取保存文件的路径 如果有返回路径 没有创建一个返回
-(NSString*)GetSavePath:(NSString *)filename{
   NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
   NSString *docPath = [pathArray objectAtIndex:0];
   return [docPath stringByAppendingPathComponent:filename];
}
//将图片保存到沙盒路径
-(void)SaveFileToDoc:(UIImage *)image path:(NSString *)path{
   NSData *data;
   if (UIImagePNGRepresentation(image)==nil) {
       data = UIImageJPEGRepresentation(image, 1);
   }else{
       data = UIImagePNGRepresentation(image);
   }
   [data writeToFile:path atomically:YES];
   //保存之后通知unity 执行对应的回调 
   //UnitySendMessage 是用来给unity发消息的  有三个参数 1.挂载对应回调脚本的物体名 2.回调函数的名称 3.对应回调上的参数
   UnitySendMessage("Canvas", "Message", "Temp.jpg");
}
#pragma mark 图片处理方法
//图片旋转处理
- (UIImage *)fixOrientation:(UIImage *)aImage {
   CGAffineTransform transform = CGAffineTransformIdentity;
   
   switch (aImage.imageOrientation) {
       case UIImageOrientationDown:
       case UIImageOrientationDownMirrored:
           transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);
           transform = CGAffineTransformRotate(transform, M_PI);
           break;
           
       case UIImageOrientationLeft:
       case UIImageOrientationLeftMirrored:
           transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
           transform = CGAffineTransformRotate(transform, M_PI_2);
           break;
           
       case UIImageOrientationRight:
       case UIImageOrientationRightMirrored:
           transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);
           transform = CGAffineTransformRotate(transform, -M_PI_2);
           break;
       default:
           break;
   }
   
   switch (aImage.imageOrientation) {
       case UIImageOrientationUpMirrored:
       case UIImageOrientationDownMirrored:
           transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
           transform = CGAffineTransformScale(transform, -1, 1);
           break;
           
       case UIImageOrientationLeftMirrored:
       case UIImageOrientationRightMirrored:
           transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);
           transform = CGAffineTransformScale(transform, -1, 1);
           break;
       default:
           break;
   }
   
   // Now we draw the underlying CGImage into a new context, applying the transform
   // calculated above.
   CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,
                                            CGImageGetBitsPerComponent(aImage.CGImage), 0,
                                            CGImageGetColorSpace(aImage.CGImage),
                                            CGImageGetBitmapInfo(aImage.CGImage));
   CGContextConcatCTM(ctx, transform);
   switch (aImage.imageOrientation) {
       case UIImageOrientationLeft:
       case UIImageOrientationLeftMirrored:
       case UIImageOrientationRight:
       case UIImageOrientationRightMirrored:
           // Grr...
           CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage);
           break;
           
       default:
           CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);
           break;
   }
   // And now we just create a new UIImage from the drawing context
   CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
   UIImage *img = [UIImage imageWithCGImage:cgimg];
   CGContextRelease(ctx);
   CGImageRelease(cgimg);
   return img;
}
@end
//由于C++编译器需要支持函数的重载,会改变函数的名称,因此dll的导出函数通常是标准C定义的。
//这就使得C和C++的互相调用变得很常见。但是有时可能又会直接用C来调用,不想重新写代码,
//让标准C编写的dll函数定义在C和C++编译器下都能编译通过,通常会使用以下的格式:(这个格式在很多成熟的代码中很常见)
#if defined(__cplusplus)
extern "C" {
#endif
   //导出接口供unity使用
   void IOS_OpenCamera(){
       IOSCameraController *app = [[IOSCameraController alloc]init];
       UIViewController *vc = UnityGetGLViewController();
       [vc.view addSubview:app.view];
       [app OpenTarget:UIImagePickerControllerSourceTypeCamera];
   }
   void IOS_OpenAlbum(){
       IOSCameraController *app = [[IOSCameraController alloc]init];
       UIViewController *vc = UnityGetGLViewController();
       [vc.view addSubview:app.view];
       [app OpenTarget:UIImagePickerControllerSourceTypePhotoLibrary];
   }
#if defined(__cplusplus)
}
#endif

unity3d 调用脚本IOSAlbumCamera.cs ,开始准备用www加载本地图片,但是好像www和UnityWebRequest,但是这个在IOS上面会报错,具体错误下方贴出,所以用了万能的IO加载

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System.Runtime.InteropServices;
using UnityEngine.Networking;
using System.IO;

public class IOSAlbumCamera : MonoBehaviour
{
   [SerializeField] private Button _openCamera; //打开相机按钮
   [SerializeField] private Button _openAlbum; //打开相册按钮
   [SerializeField] private RawImage _image; //用于显示的图片
   //引入在oc中定义的那两个方法
   [DllImport("__Internal")]
   private static extern void IOS_OpenCamera();
   [DllImport("__Internal")]
   private static extern void IOS_OpenAlbum();

   void Awake()
   {
       //为两个button添加点击事件
       _openCamera.onClick.AddListener(IOS_OpenCamera);
       _openAlbum.onClick.AddListener(IOS_OpenAlbum);
   }
   //ios回调unity的函数
   void Message(string filenName)
   {
       Debug.Log("<<<<<<<<<<<<<<<<<<回调>>>>>>>>>>>>>>>>>>>>>>>");
       Debug.Log("fileName:     " + filenName);
       //我们传进来的只是文件名字 这里合成路径
       string filePath = Application.persistentDataPath + "/" + filenName;
       Debug.Log("filePath:         " + filePath);
       //开启一个协程加载图片

       double startTime = (double)Time.time;
       //创建文件读取流
       FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
       fileStream.Seek(0, SeekOrigin.Begin);
       //创建文件长度缓冲区
       byte[] bytes = new byte[fileStream.Length];
       //读取文件
       fileStream.Read(bytes, 0, (int)fileStream.Length);
       //释放文件读取流
       fileStream.Close();
       fileStream.Dispose();
       fileStream = null;

       //创建Texture
       int width = 300;
       int height = 372;
       Texture2D texture = new Texture2D(width, height);
       texture.LoadImage(bytes);

       _image.texture = texture;




       //StartCoroutine(HttpGetTexture(filePath));
   }


   IEnumerator HttpGetTexture(string url)
   {
       Debug.Log("HttpGetTexture1111111111111111111111");
       WWW www = new WWW(url);

       if (!www.isDone)
           yield return www;
       else
       {
           Debug.Log("2222222222222222222222222" );
           if (www.error == null)
           {
               Debug.Log("3333333333333333333333333333333333333");
               Texture2D texture2D = new Texture2D(128, 128);
               texture2D.LoadImage(www.bytes);
               _image.texture = texture2D;
           }
           else
               Debug.LogError("Error:    " + www.error);
       }
   }
}

导出Xcode,打包真机调试。

1.在Build的时候[图片] MapFileParser.sh: Permission denied

[图片]错误信息

解决方法,打开ios的终端,运行chmod +x /Users/ccc/Desktop/Album 下午10.47.06/MapFileParser.sh

/User后面为MapFileParser.sh 所在的地方,根据自己的地方填写正确。

2.在真机运行的时候,用www和UnityWebRequest报错,改用IO加载图片。报错的原因是iOS9对应用通讯安全策略进行了升级, 已不再支持http这种不安全的协议,新特性要求App内访问的网络必须使用HTTPS协议。当然也可以使用Http请求,但是需要Info.plist添加文件。但是还是建议跟随时代潮流。

错误信息

原始工程链接

链接: https://download.csdn.net/download/qq_32141141/10988944.

2016-09-13 13:49:41 chy_xfn 阅读数 3721
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

相信很多人都喜欢在创建脚本时添加这样的注释说明,以前做Android开发用Eclipse设置过这样的脚本模板,所以也想在Unity上添加,从网上搜索资料得,首先找到Unity安装目录下的(注意:修改的是Unity脚本模板而不是vs或者momo里的)

“Unity\Editor\Data\Resources\ScriptTemplates ”

打开“81-C# Script-NewBehaviourScript.cs”文件,如下:

using UnityEngine;
using System.Collections;

public class #SCRIPTNAME# : MonoBehaviour {

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {

    }
}

看到了吧,这个和我们在Unity创建C#脚本时自动生成的是不是一样,唯一区别的是宏#SCRIPTNAME#,这个宏会跟随我们创建的脚本名变化,这个功能也是我们自定义脚本模板的重要功能,后来我在这个文件的最上面添加了我的自定义注释,然后加了个自定义的#CreateTime#,是想在创建脚本时显示创建时间。结果发现这个时间一直显示为#CreateTime#不会变的。原来#SCRIPTNAME#是Unity自定义的一个宏,所以你想添加时间,必须也要自定义。然后自己找了好久也没找到在哪修改,最后找了一个直接在项目里修改的办法。如果修改本地文件的话,每次创建新项目都会生成这个新脚本模板,同时还要在项目里修改添加时间自定义。再加上我只喜欢在正式项目里才想加这个注释模板,有些并不想加,所以干脆把其他注释全部的添加到项目里,方便管理,具体如下:

该脚本需放到Editor文件夹内

using UnityEngine;
using System.Collections;
using System.IO;

public class ChangeScriptTemplates : UnityEditor.AssetModificationProcessor
{
     // 添加脚本注释模板
     private static string str = 
     "// ========================================================\r\n"
     +"// 描 述:\r\n"
     +"// 作 者:xfn \r\n"
     +"// 创建时间:#CreateTime#\r\n"
     +"// 版 本:v 1.0\r\n"
     +"// ========================================================\r\n";

     // 创建资源调用
     public static void OnWillCreateAsset(string path)
     {
        // 只修改C#脚本
        path = path.Replace(".meta", "");
        if (path.EndsWith(".cs"))
        {
            string allText = str;
            allText += File.ReadAllText(path);
            // 替换字符串为系统时间
            allText = allText.Replace("#CreateTime#",System.DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"));
            File.WriteAllText(path, allText);
        }
     }
}
没有更多推荐了,返回首页