2014-04-25 23:11:59 u012276084 阅读数 2681

     在我们学习Unity3D之前,我们要保障Unity3D已安装并且正确的安装了,在我们安装的文件夹下有两个文件夹,一个是Editor,用于Unity3D的编辑,另一个文件夹是MonoDevelop,用于我们的脚本编写。(微笑友情提示:Unity3D要正确安装哟,Unity3D简称U3D)

     下面我们就进入U3D的界面学习,看图:

下面我就不一一对每个菜单项进行详细的说明,做个简单的介绍,相信大家都知道它的意思。

文件菜单 主要有新建场景、打开场景、保存场景、另存为、新建工程、打开工程、保存工程等。

编辑菜单 主要有剪切、复制、粘贴、删除、查找、选择所有、播放、暂停、逐步调试、工程设置、渲染设置、网络、图像清晰度等的设置。

资源菜单 主要有创建(创建脚本、预制体、材质、物理材质等存放于工程目录)、导入新的资源、导入包、到处包、刷新等。

游戏对象按钮 主要有创建空对象、创建其它对象(比如:立方体、球体、胶囊、平面、圆柱体、地形、各种灯光、玩具、照相机、风、粒子效果等)等。

组件阿牛 主要有效果、物理引擎、声音、脚本、渲染等。

窗口按钮 主要有切换下一个窗口、切换上一个窗口、布局、场景、游戏、清单、工程、监视面板、动画、版本控制、动作等。

帮助按钮 主要是U3D的关于,更新,错误报告、商店、帮助等。


层次清单:工程所创建的对象,便于管理

工程资源:工程的所有资源

监视面板:主要是对象的属性


编辑场景:能够观察场景中所有的物体,并且可以调整物体的位置,大小,旋转等

游戏场景:玩家所真正能够看到的画面


如果以上内容有纰漏,请纠正,谢谢配合!敲打

敬请期待下一章!奋斗

2016-01-30 09:43:30 sinat_33848542 阅读数 62

    初学unity3D软件,写了个小球吃东西加分的游戏,根据siki的教程,自己添加了物体吃完后游戏自动复位的代码以及复位前的延时代码。

    主要了解了材质的使用,脚本的编写,component添加,颜色添加,刚体相关知识。

代码如下:

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
 
public class player : MonoBehaviour {
	private Rigidbody rd;
    public int force = 5;
    private int score = 0;
    public Text text;
    public GameObject wintext;
 
 
	// Use this for initialization
	void Start () {
		rd = GetComponent<Rigidbody> ();
	}
	
	// Update is called once per frame
	void Update () {
		float h = Input.GetAxis ("Horizontal");  //前后控制
        float v = Input.GetAxis ("Vertical");  //左右控制
		rd.AddForce (new Vector3 (h,0v)*force);
	
	}
    void OnCollisionEnter(Collision collision)//碰撞检测
    {
        if (collision.collider.tag == "food")
        {
            Destroy(collision.collider.gameObject);//碰撞检测后消除,物体属性是物体,所以碰撞后小球会产生一个力使球停顿一下
        } 
    }
    IEnumerator wait(int t)
    {
        yield return new WaitForSeconds(t);//延时控制 
        Application.LoadLevel("main");//时间t后重新加载
    }
    void OnTriggerEnter(Collider collider)//触发检测,食物属性修改了一下,使其作为触发器而不是物体了.
    {
        if (collider.tag == "food")
        {
            score++; 
            text.text = "得分:"+score.ToString();
            Destroy(collider.gameObject);
            if (score == 8)
            {
                wintext.SetActive(true);
                StartCoroutine(wait(3));       
            }
           
        }
    }
 
}

2019-03-04 09:19:39 qq_32141141 阅读数 42

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.

2018-12-21 17:53:07 programmer_feng 阅读数 113

其实学习编程的人都会有如下感悟:学习和实际动手做项目、开发软件完全是两种概念,Unity3D游戏开发的学习过程亦是如此。刚开始学习Unity3D的时候,明明已经认真的看着教程内容,自己动手做了一遍,但脑海里的知识总是模模糊糊的,处于似会似不会的状态。

无法区分“真会”与“假会”往往就是我们学习过程中的拦路虎,其实不止Unity3D,每一门编程语言的学习或者说具有丰富内容的技艺都是如此。唯有通过不断练习和使用才能加深我们的应用能力,以达到求职标准。如何稳步提升Unity3D游戏开发能力,我建议大家从夯实基础和稳步进阶两部分抓起。

首先是基础部分,要知道再复杂的工程或项目都是由一点点小部件累积而成的。做练习也一样,先具体的开发相关模块的功能小部件,当然代码和项目完成时会不一样,但贵在自己摸索和思考。然后再将这些小部件一一做组合,以小见大,以易解难,完成项目。我们学习时的大部分课程都是线性的一字长蛇阵,一步步跟着老师做,不懂也跟着抄写代码。老师代码简洁有力,同学们也能更好的理解,但练习不一样,这需要你在学会的知识做变通,举一反三,而且还需要不断的修改代码以达到实现更健全的项目。

其次是进阶部分,练习项目的扩展分为知识扩展和知识扩展。当练习过程中,你有新的项目设计和实现方法都可以大胆的去勾勒和敲打出来,这时你的项目是自由奔放的,不会像课堂里经典项目因为你初学懵懂,所以啥也不敢改怕引起错误。这部分是实实在在的锻炼你独立开发项目的能力,工作可没有教程和答案,不迈向这一步到头来是会吃亏的。另一方面就是知识的扩展,课堂上只会教你这个方法解决这个问题,一笔带过。虽然你理解代码的意思也能熟练的使用,但这不够,你得了解该方法具体实现代码,找出该方法同类有哪些,该方法常见的使用错误方式,错误会弹出什么内容?并为它做个小小的总结,顺便学习了这个类型的常用方法。

其实提升编程能力的唯一能力就是熟能生巧,通过大量练习,加之自己的反复总结和思索,才能加深知识理解,提高代码效率。

2017-07-14 13:58:21 u012632851 阅读数 3800

版本:unity 2017.1  语言:C#

 

总起:

Unity2D物理引擎是基于Box2D的,嘛,在这一点上cocos也不例外,其他的软件要做2D物理效果的话基本上也会用该引擎。Box2D本身是一个免费开源的物理引擎,由C++编写而成。

 

https://github.com/erincatto/Box2D,Github上有官方实例,可以下下来玩玩。

 

2D物理的设置:

通过打开Edit -> Project Settings -> Physics 2D就可以设置全局的2D物理效果,以下是默认设置的截图:



Gravity:作用于所有拥有Rigidbody2D组件游戏对象的重力值,该值一般来说是y轴的负半轴方向;

 

Default Material:默认的Physics Material 2D物理材质,用于Collider 2D,该材质只有两种数值:Friction摩擦系数、Bounciness弹力系数;

 

Velocity Iterations:决定速度影响的迭代次数,值越高,物理模拟越精确,但CPU消耗也越大;

 

Position Iterations:决定位置影响的迭代次数,值越高,物理模拟越精确,但CPU消耗也越大;

 

Velocity Threshold:速度阈值,速度在该值之下的GameObject会被视为非弹性碰撞;

 

Max Linear Correction:最大线性矫正,用于防止过冲;

 

Max Angular Correction:最大角速度校正,用于防止过冲;

 

Max Translation Speed:Rigidbody 2D最大的线性速度;

 

Max Rotation Speed:Rigidbody 2D最大的角速度;

 

Min Penetration For Penalty:(2017版中可设置,以后如果是2017的特性,直接表明2017)Collider之间分离前的最小渗透半径;

 

Baumgarte Scale:解决重叠问题的缩放因子;

 

Baumgarte Time of Impact Scale:同上,重叠问题的因子;

 

Time to SleepRigidbody 2D静止状态多久时间(单位秒)后进入睡眠状态;

 

Linear Sleep Tolerance:线性速度阈值,决定多少速度以下算是静止状态;

 

Angular Sleep Tolerance:角速度阈值,决定多少角速度以下算是静止状态;

 

Queries Hit TriggersCollider 2D被标记为Trigger后,任何的物理查询是否能触发Trigger,类似Linecast、Raycast,勾选则会触发;

 

Queries Start In Colliders:勾选此框的情况下,在Collider 2D内部时射线检测会返回该Collider,否则不会;

 

Change Stops Callbacks:勾选此框时,当Collider被移出或删除,碰撞反馈会立即停止;

 

Callback On Disable:官方截图上没有,但确实有该属性。意思应该是Disable时会回调。后两个参数我没有测试,貌似是针对一帧内调用,个人感觉没什么特别的用处,保持默认就好;

 

Layer Collision Matrix:层碰撞矩阵,勾选之间的层能产生碰撞。

 

Rigidbody 2D:

3D的刚体有区别,Rigidbody 2D有三种类型,但是实现的功能是一样的,而且运动的物体同样在Collision Detection中选择Continuous,不然运动物体过快的话可以直接穿过去。

 

相比于3D刚体3个轴上都可以运动,Rigidbody 2D只能在x、y轴上运动,而随着z轴旋转,当然横版游戏角色的话,一般会选择Freeze Rotation Z冻结Z轴上的旋转。

 

官方文档是从最复杂的动态刚体开始介绍的,让我们反着来。

 

Static 静态刚体

静态刚体就像是个拥有无限质量的物体固定在那边一样,它只会与Dynamic的其他刚体发生碰撞,两个静态刚体的碰撞是没有效果的。如下图所示,能调节的属性十分有限:



Body Type:肯定是Static,所以才是静态刚体;

 

Material:选择物理材质,物理材质按照以下顺序查找:

1.Collider 2D本身的物理材质;

2.Rigidbody上的物理材质;

3.全局设置下的物理材质。

    一直有个疑惑是如果上面都没有设置,那么物理材质会选择哪个,测试下来应该是这样的,默认是摩擦系数0.4、弹力系数0。

 

Simulated:是否在当前的物理环境中模拟,取消勾选该框类似于Disable Rigidbody,但使用这个参数更加高效,因为Disable会销毁内部产生的GameObject,而取消勾选Simulated只是禁用。

 

Kinematic 动力学刚体

动力学刚体不受重力和力的影响,而受用户的控制,需要使用类似Rigidbody2D.MovePosition、Rigidbody2D.MoveRotation的方法。它于静态刚体一样,只与动态刚体会发生碰撞。

 

嗯,而且质量应该算是无限大,所以它在运动的时候会撞开所有的动态刚体。



Body Type:Kinematic表明是运动学刚体;

 

Material:同上;

 

Simulated:同上;

 

Use Full Kinematic Contacts:启用该选项后,它的行为会类似于动态刚体与其他所有刚体都发生碰撞,但它还是手用户控制的,并且拥有无限大的质量。

 

Collision Detection:建议选择Continuous,不然速度过快时,物体会直接穿过去,嘛,当然要保证这样运动连续的话,CPU的一点点性能贡献是必要的。

 

Sleeping Mode:

    1.Never Sleep,禁用睡眠状态,尽量不要使用该选项,会影响系统资源;

    2.Start Awake,初始状态是醒着的;

    3.Start Asleep,初始状态是睡眠状态,当然会被其他碰撞而唤醒。

 

Interpolate:改变物体移动时内插值的行为,如果物体移动时发生了抖动现象,请使用该参数。

    1.None,不使用平滑插值;

    2.Interpolate,根据上一帧的位置进行插值;

    3.Extrapolate,根据下一阵的位置进行插值。

 

Constraints:用于冻结x、y轴的移动或z轴的旋转。

 

Dynamic 动态刚体

动态刚体会与其他的所有刚体发生碰撞,注意不要主动修改Transform的位置和角度,刚体内部会自动使用速度来模拟移动。需要时请使用Force函数来进行移动、旋转。



Body Type:Dynamic表明是动态刚体;

 

Material:同上;

 

Simulated:同上;


Use Auto Mass:勾选该选项框后,Rigidbody 2D可以自动根据Collider生成质量;

 

Mass:物体的质量;

 

Linear Drag:线性速度阻力;

 

Angular Darg:角速度阻力;

 

Gravity Scale:重力影响的缩放因子;

 

Collision Detection:同上;

 

Sleeping Mode:同上;

 

Interpolate:同上;

 

Constraints:同上。

 

这样看下来,对比很清晰吧,动力学刚体和动态刚体就区别在于动态刚体多了质量和阻力值。

 

又写了五页了,还以为一篇直接能把2D后面的全介绍了。不过要做的话还是认真点吧,Collider、Joint和Effector就留到下一篇。

 

个人:

Unity正式进入2017了文档也更新了,我这边也就顺势推到2017了,其实没太大更新,Sprite功能继续完善,然后Animation出了个录像功能,还蛮好用的。

 

最近自己也算是跌到了低谷,投了大概一个月的简历,Unity的面试邀请一次都没有,失败吗?自己到底哪里不足了?自省之下却得不出个答案。

 

不过现在想想那又怎样?失败了,那又怎么样?现在的失败不过未来成功后的调料而已,一帆风顺的人生有什么意思?一个游戏中你的能力已经秒天秒地秒空气了又有什么意思?

 

真的感觉很抱歉呢,我在日漫中其他什么都没有学到,只学到了一点,即使被打倒了一百次,也要在第一百零一次的时候站起来。而我现在不过是第一次失败罢了。

 

想想纵使黑暗之魂这样对新人恶意满满的游戏,我都跨过了,还有什么跨过不了的?到最后扒开里面的各种恶意都成了趣味。所以生活的恶意尽管来,退却了一步算我输,我会让你看到我的执念!


没有更多推荐了,返回首页