Compare commits

...
317 Commits
Author SHA1 Message Date
lishuo 11693c40af 忽略video插件 2022-06-30 14:43:01 +08:00
lishuo 4d4f8feb8b c2课程同步 2022-06-30 14:39:13 +08:00
lishuo 46f7c2d4b1 解决阻力设置点击无效的bug 2022-06-28 11:03:10 +08:00
lishuo 06b9051b3c c2同步课程命令 2022-06-24 18:03:36 +08:00
lishuo 701ec3069b C2课程同步问题 2022-06-23 18:55:08 +08:00
lishuo 84b3e1e7a4 移除测试代码 2022-06-21 18:55:13 +08:00
lishuo 573b96d86c 拉力曲线性能优化&解决划船时间误差问题 2022-06-21 17:49:43 +08:00
lishuo 6c9b3f825a 解决没有设备号的问题 2022-06-15 18:07:06 +08:00
lishuo 6e091bd99c anroid ble jar包调整 2022-06-15 16:58:22 +08:00
lishuo 610c98f9b8 解决c2表头设定课程后抖动问题,设备断开失败问题 2022-06-15 16:42:07 +08:00
lishuo 0202814f67 心率,阻力逻辑调整 2022-06-14 18:37:58 +08:00
lishuo f25d0b7b8c 蓝牙断开重连相关逻辑优化 2022-06-13 18:59:02 +08:00
lishuo 87a0e7fb6d 划船机优化 2022-06-10 19:31:07 +08:00
lishuo 2f64aa494f 移动端蓝牙优化 2022-06-09 14:52:50 +08:00
lishuo 72f254af2a 蓝牙重复初始化问题 2022-06-09 14:52:45 +08:00
lishuo 6b3dd70c61 设备连接界面断开逻辑调整 2022-06-08 17:25:02 +08:00
lishuo 46b6c7fa01 设备连接稳定性 2022-06-08 16:22:07 +08:00
Caiyanpeng c333086e30 重置问题 2022-06-08 13:55:35 +08:00
Caiyanpeng c7afcbb01f Merge branch 'dev_cyp' into dev_cyp1
# Conflicts:
#	Assets/Scripts/UI/Prefab/Panel/RowerHomeScript.cs
2022-06-07 11:32:46 +08:00
Caiyanpeng ff878d5d50 修改断线重连自动开始问题 2022-06-07 11:32:23 +08:00
lishuo b236e939f4 graph优化
# Conflicts:
#	Assets/Scripts/UI/Prefab/Panel/RowerHomeScript.cs
2022-06-06 19:55:08 +08:00
Caiyanpeng bfc56dded5 0606修改 2022-06-06 18:54:28 +08:00
Caiyanpeng 6effadc1e9 增加长时间保存,解决取影子以后后续请求失效问题(使用unity的请求库) 2022-06-06 09:09:20 +08:00
Caiyanpeng d498dd9148 日志包 2022-06-02 15:52:10 +08:00
lishuo 71c9907c89 UImanager show方法会产生多余的HomeController 2022-06-01 19:49:15 +08:00
Caiyanpeng 154252e3c3 Merge remote-tracking branch 'origin/dev_ani3' into dev_cyp 2022-06-01 16:24:36 +08:00
lishuo cda569afd5 性能优化 2022-06-01 16:10:42 +08:00
Caiyanpeng 475250e795 Merge remote-tracking branch 'origin/dev_ani3' into dev_cyp 2022-06-01 16:10:35 +08:00
lishuo c579c1b130 Merge remote-tracking branch 'origin/dev_cyp' into dev_ani3 2022-06-01 10:50:16 +08:00
lishuo d9848e4e9d 设备连接界面微调&划船机本地记录过滤 2022-06-01 10:24:23 +08:00
Caiyanpeng 622aaa3b6d 重连后续修改 2022-06-01 09:54:20 +08:00
lishuo e7af21b126 pc设备连接界面微调 2022-05-31 19:43:50 +08:00
Caiyanpeng bfa9f5f998 Merge remote-tracking branch 'origin/dev_ani3' into dev_cyp 2022-05-31 18:42:13 +08:00
Caiyanpeng 3f8c189ad4 断线重连取数据逻辑 2022-05-31 18:40:32 +08:00
lishuo a1010091f8 设备连接界面文案与交互调整 2022-05-31 18:25:53 +08:00
Caiyanpeng 167a424505 Merge remote-tracking branch 'origin/dev_ani3' into dev_cyp
# Conflicts:
#	Assets/Scripts/UI/Prefab/Panel/RowerHomeScript.cs
2022-05-31 16:51:37 +08:00
Caiyanpeng ff6d61a606 修改其他的 2022-05-31 16:51:07 +08:00
lishuo 2524e3a004 划船机实时保存 2022-05-31 16:47:21 +08:00
lishuo 95df03e540 chart内存性能优化 2022-05-31 14:43:05 +08:00
Caiyanpeng be687d6b77 适配v1表头,性能优化一波 2022-05-11 17:11:48 +08:00
Caiyanpeng edc629ed75 5.9修改暂存 2022-05-10 18:43:41 +08:00
Caiyanpeng cfa1cc4f7b 4.29计算逻辑修改 2022-04-29 18:39:41 +08:00
Caiyanpeng 3c4ecf3e83 曲线调整 2022-04-29 08:58:42 +08:00
Caiyanpeng f47f5c9ff6 0426动画等修改 2022-04-27 14:48:06 +08:00
Caiyanpeng affc775226 调整后提交 2022-04-20 18:22:54 +08:00
Caiyanpeng a2de06fede Merge branch 'dev_ani2' into dev_ani3
# Conflicts:
#	Assets/Scripts/UI/Prefab/Rower/RowerMultiModeScript.cs
2022-04-15 17:13:55 +08:00
Caiyanpeng 2f9dd43e07 1s 2022-04-15 17:13:34 +08:00
Caiyanpeng c8076494fb 3s 2022-04-15 11:14:27 +08:00
Caiyanpeng 41240b1398 动画修改一波 2022-04-15 11:14:22 +08:00
Caiyanpeng f383c54507 4.14修改,设备连接去掉ftms骑行台 2022-04-14 19:18:44 +08:00
Caiyanpeng 29e7219c21 位移动画 2022-04-13 18:08:55 +08:00
Caiyanpeng d44638354d 4.13修改细节,位移动画前暂存 2022-04-13 15:44:02 +08:00
Caiyanpeng 874dec5ec6 新版本动画:上下滑动切换有箭头 2022-04-12 19:08:58 +08:00
Caiyanpeng 7780dc5ee5 3d翻转 2022-04-11 11:40:02 +08:00
Caiyanpeng 95ab695632 之前动画加上排名变化 2022-04-07 14:19:58 +08:00
Caiyanpeng 92d0579060 中文版 2022-04-07 09:23:44 +08:00
Caiyanpeng 0a4925bb39 修改bug 2022-04-02 18:15:09 +08:00
Caiyanpeng 30e09c9c7a 修改细节,修复bug 2022-04-01 18:07:16 +08:00
Caiyanpeng 06aefb93c4 适配C2划船机课程和menu 2022-03-30 18:25:51 +08:00
Caiyanpeng e0649f7ea1 修改新设计稿,保存每次划船的影子id;修改细节,增加c2适配前暂存 2022-03-29 18:12:21 +08:00
Caiyanpeng ab653b994f 适配c2;新版设计稿;对战切换手势;主逻辑接通;使用think的阻力值,修改影子模式船位置 2022-03-25 18:02:34 +08:00
Caiyanpeng e6f3e2ecfa Merge branch 'dev_rower' into dev_cyp
# Conflicts:
#	ProjectSettings/ProjectSettings.asset
2022-03-09 09:12:42 +08:00
Caiyanpeng e3f5280d94 暂存 2022-03-09 09:11:53 +08:00
Caiyanpeng c3514df331 请求公开线路;增加移动版 2022-03-03 15:06:13 +08:00
Caiyanpeng 01df299251 邮件功能完成 2022-03-02 17:54:06 +08:00
Caiyanpeng b039388a59 改为线上 2022-02-25 09:31:17 +08:00
Caiyanpeng 0c42fbe2cd Merge remote-tracking branch 'origin/dev_lishuo' into dev_cyp 2022-02-24 14:48:50 +08:00
Caiyanpeng 7e67184248 不给功率;修改比赛卡片有海拔图的异常问题 2022-02-24 11:35:26 +08:00
lishuo c1c93c2a60 loading页面优化 2022-02-24 11:33:24 +08:00
Caiyanpeng 353c19662c Merge remote-tracking branch 'origin/dev_lishuo' into dev_cyp 2022-02-24 08:58:14 +08:00
Caiyanpeng 3b0ffd78e7 分享文案 2022-02-24 08:58:03 +08:00
lishuo ed9dc53093 loading60%问题,只要加载到第一个瓦片的高度就可以直接骑行 2022-02-23 18:14:31 +08:00
lishuo 6a0bd67a6e Merge remote-tracking branch 'origin/dev_cyp' into dev_lishuo 2022-02-23 11:31:23 +08:00
Caiyanpeng 1e350fbb4d 更改为测试服务器,广告队列判空 2022-02-23 11:29:41 +08:00
Caiyanpeng 768f8261da 英文版本,pc分享功能,移动端fb分享,修改细节 2022-02-22 18:11:26 +08:00
lishuo 0c1c2ed382 保存优化&本地记录自动上传 2022-02-21 16:16:35 +08:00
Caiyanpeng 2c7d02ec9a 修改细节,开始搞pc 2022-02-18 18:12:31 +08:00
lishuo f5294b0d39 Merge remote-tracking branch 'origin/dev_cyp' into dev_lishuo
# Conflicts:
#	Assets/Scripts/App.cs
2022-02-18 15:49:54 +08:00
Caiyanpeng 365fab22d4 修改细节 2022-02-18 15:48:23 +08:00
Caiyanpeng 1b3743a135 修改活动逻辑;增加一些接口;可弹多个广告 2022-02-17 16:56:18 +08:00
Caiyanpeng 1148e29379 活动暂存 2022-02-16 18:22:27 +08:00
Caiyanpeng 7c1d1e797c 开放划船机,增加阻力设置 2022-02-11 17:38:23 +08:00
Caiyanpeng e231d3540e 活动暂存 2022-02-11 17:26:36 +08:00
lishuo 5f0efe3995 修复ios蓝牙关闭功率不变的问题 2022-02-11 17:00:28 +08:00
Caiyanpeng 17aee7a740 修改bug 2022-02-11 13:46:38 +08:00
Caiyanpeng c12df53c18 ios快捷登录 2022-01-27 16:54:20 +08:00
Caiyanpeng a625db3ebe 短通知bug;安卓更新中文补全 2022-01-26 17:25:07 +08:00
Caiyanpeng 7476af7701 手机端直接隐藏通知;安卓64位 2022-01-26 13:48:11 +08:00
Caiyanpeng c4bcb36356 Merge remote-tracking branch 'origin/dev_lishuo' into dev_cyp 2022-01-26 10:53:46 +08:00
Caiyanpeng 5edd784080 消息通知逻辑 2022-01-26 10:53:11 +08:00
lishuo 0644421279 loading页国旗默认白色图片 2022-01-26 10:24:47 +08:00
Caiyanpeng 28487b295b 进入比赛默认3d 2022-01-25 18:48:37 +08:00
Caiyanpeng 2abb2d81a2 Merge remote-tracking branch 'origin/dev_lishuo' into dev_cyp 2022-01-25 18:29:27 +08:00
Caiyanpeng 1271e8e5d9 设置通知默认不显示 2022-01-25 18:29:22 +08:00
lishuo f16883465f 观察者切换人物大小问题 2022-01-25 18:25:40 +08:00
Caiyanpeng 3da12c3054 Merge remote-tracking branch 'origin/dev_lishuo' into dev_cyp 2022-01-25 17:17:17 +08:00
Caiyanpeng 0a9adb19e6 修改动画;漏掉的汉化;上传图标 2022-01-25 17:15:05 +08:00
lishuo d4fbeeefc2 赛事默认3d地图&观察者人物动画bug修复&重新连接根据用户id筛选 2022-01-25 17:14:19 +08:00
lishuo 37873427e3 PC点击区域&PFbutton微调 2022-01-25 11:17:42 +08:00
lishuo 5340d3d58b Merge remote-tracking branch 'origin/dev_cyp' into dev_lishuo 2022-01-25 09:28:20 +08:00
Caiyanpeng cd162f3325 长通知和切换场景保留消息 2022-01-24 15:41:04 +08:00
lishuo 9d48c05ef0 赛事默认3d视角&loading页面国旗问题 2022-01-24 11:39:48 +08:00
Caiyanpeng 7bb5bafbd2 ios端google;修改ios打包时pod数据源为清华 2022-01-20 16:30:58 +08:00
Caiyanpeng 58a8233697 google 登录暂存 2022-01-19 13:42:12 +08:00
Caiyanpeng 45b3ee5bbc 工具栏问题修改,中文 2022-01-13 22:56:47 +08:00
Caiyanpeng 0458a23c20 Merge remote-tracking branch 'origin/dev_lishuo' into dev_cyp 2022-01-13 20:00:09 +08:00
Caiyanpeng 2bf534775f dotween允许回调 2022-01-13 20:00:04 +08:00
lishuo 8f022e83a6 赛事人物微调 2022-01-13 19:57:49 +08:00
Caiyanpeng fed54ad85b Merge remote-tracking branch 'origin/dev_lishuo' into dev_cyp 2022-01-13 18:58:01 +08:00
lishuo 5bc1bec425 赛事loading和退出弹窗调整 2022-01-13 18:57:30 +08:00
Caiyanpeng 5489fa2a24 Merge remote-tracking branch 'origin/dev_lishuo' into dev_cyp 2022-01-13 18:50:55 +08:00
Caiyanpeng d89deba02c 修改bug 2022-01-13 18:50:51 +08:00
lishuo 8a2d4f7b85 Merge remote-tracking branch 'origin/dev_cyp' into dev_lishuo 2022-01-13 17:13:08 +08:00
lishuo d33e130eca 退出窗口层级微调 2022-01-13 17:11:04 +08:00
Caiyanpeng 0a1ba5fbde Merge remote-tracking branch 'origin/dev_lishuo' into dev_cyp 2022-01-13 16:53:05 +08:00
Caiyanpeng e82592722f 首页弹消息bug;隐藏google 2022-01-13 16:53:01 +08:00
lishuo e70a84db98 骑行退出面板层级调整至modalpanel 2022-01-13 16:48:37 +08:00
Caiyanpeng 697818bae4 Merge remote-tracking branch 'origin/dev_lishuo' into dev_cyp 2022-01-13 15:36:20 +08:00
Caiyanpeng 4d5523e2ff fb分享;比赛页面箭头去了 2022-01-13 15:35:57 +08:00
lishuo 79ad622026 赛事loading页面条调整 2022-01-13 14:50:23 +08:00
lishuo dd1d26e9c8 pc赛事loading隐藏 2022-01-13 13:43:09 +08:00
Caiyanpeng 7a7c1ee55c google处理 2022-01-13 13:16:45 +08:00
Caiyanpeng bc5e4d14e4 Merge remote-tracking branch 'origin/dev_lishuo' into dev_cyp 2022-01-13 13:13:28 +08:00
Caiyanpeng 2fec28e7cd 打包改为移动端 2022-01-13 13:13:24 +08:00
lishuo 77414ad387 骑行结果移动端增加dnf和新记录的标识 2022-01-13 10:46:59 +08:00
Caiyanpeng 10ffd8160a Merge remote-tracking branch 'origin/dev_nonearth' into dev_cyp 2022-01-13 08:57:48 +08:00
lishuo dc4cf87bc4 在线人海拔图位置超出边界隐藏 2022-01-12 18:27:00 +08:00
Caiyanpeng c53fbffe55 增加第三方信息绑定,修改细节 2022-01-12 18:16:17 +08:00
Caiyanpeng 02111a57b1 Merge remote-tracking branch 'origin/dev_nonearth' into dev_cyp
# Conflicts:
#	Assets/Resources/UI/language.json
2022-01-12 16:56:50 +08:00
Caiyanpeng 91fa3cc82d pc版首页;安卓google登录;解决fb登录ios问题 2022-01-12 16:55:57 +08:00
lishuo 61fefda590 微调 2022-01-12 16:45:13 +08:00
lishuo f7450f0067 骑行视角增加至5级&保存逻辑增加100m不可以保存 2022-01-12 16:41:52 +08:00
Caiyanpeng f0df68bbda banner bug;maxranking修改 2022-01-12 10:29:10 +08:00
lishuo f949c531a6 我的排名微调 2022-01-11 19:08:34 +08:00
Caiyanpeng 939774bd42 Merge remote-tracking branch 'origin/dev_nonearth' into dev_cyp 2022-01-11 18:00:53 +08:00
lishuo 9aecb4ce2a 移动端兼容问题 2022-01-11 16:30:36 +08:00
Caiyanpeng 623cad18b2 Merge remote-tracking branch 'origin/dev_nonearth' into dev_cyp 2022-01-11 16:21:45 +08:00
Caiyanpeng 5672898ce4 工具栏修改 2022-01-11 16:21:13 +08:00
lishuo 90be662db1 loading页&骑行页面记忆跳转 2022-01-11 16:19:18 +08:00
Caiyanpeng 05e3d2f887 Merge remote-tracking branch 'origin/dev_nonearth' into dev_cyp 2022-01-11 13:51:13 +08:00
Caiyanpeng e20ddb9bc1 修改细节 2022-01-11 13:51:05 +08:00
lishuo bdfe1f6ee7 结果页调整 2022-01-11 13:48:06 +08:00
Caiyanpeng 27ea20b1c8 Merge remote-tracking branch 'origin/dev_nonearth' into dev_cyp 2022-01-11 11:18:18 +08:00
Caiyanpeng 5bf7635f1e pc修改 2022-01-11 11:18:09 +08:00
lishuo dbabaae032 结果页&loading页修改 2022-01-10 18:26:30 +08:00
Caiyanpeng d811eb8514 pc暂存 2022-01-10 14:59:06 +08:00
Caiyanpeng f070f5a36c 修改maplist;苹果处理 2022-01-10 10:28:03 +08:00
Caiyanpeng 7431228d2f 0107修改 2022-01-07 22:46:35 +08:00
Caiyanpeng e5067228b2 发布版本 2022-01-07 20:43:14 +08:00
Caiyanpeng e87429d528 修改细节 2022-01-07 18:22:22 +08:00
Caiyanpeng 79849bd537 Merge remote-tracking branch 'origin/dev_nonearth' into dev_cyp 2022-01-07 15:11:44 +08:00
Caiyanpeng 9fb819b6fe banner种类增加;集合详情增加作者;排行榜轮换功能 2022-01-07 15:11:40 +08:00
lishuo 082b45c43c 实时保存微调 2022-01-07 14:33:31 +08:00
Caiyanpeng fa0d9e973c Merge remote-tracking branch 'origin/dev_nonearth' into dev_cyp 2022-01-07 11:05:43 +08:00
Caiyanpeng f5385e31d6 修改nav;增加消息弹窗 2022-01-07 11:05:32 +08:00
lishuo 300c61a883 推荐banner增加赛事 2022-01-07 11:03:49 +08:00
lishuo 16a89b07b8 推荐api&骑行结果日期格式已经跳转到记录 2022-01-07 10:34:16 +08:00
lishuo 14e9e8e23b Merge remote-tracking branch 'origin/dev_cyp' into dev_nonearth
# Conflicts:
#	Assets/Scripts/Scenes/MainController.cs
2022-01-06 18:03:12 +08:00
lishuo 43dc844998 loading页面Tips调整&骑行卡顿问题解决 2022-01-06 18:01:48 +08:00
Caiyanpeng 2d38b63c91 暂存 2022-01-06 17:51:17 +08:00
lishuo 0628bd3716 loading调整&骑行动画&角度手势方向调整 2022-01-06 10:58:52 +08:00
Caiyanpeng ba36014712 微调 2022-01-05 14:02:51 +08:00
Caiyanpeng 537ae2d6ed banner手势滑动,点击效果;自动滚动 2022-01-05 09:24:06 +08:00
Caiyanpeng 7f7318fb36 消息轮播bug修改;内容滚动匀速播放;收藏图标变大 2021-12-31 11:23:16 +08:00
Caiyanpeng 333c99fb46 一波小改动 2021-12-30 16:51:04 +08:00
Caiyanpeng c5500c269f Merge remote-tracking branch 'origin/dev_nonearth' into dev_cyp 2021-12-29 20:31:34 +08:00
lishuo 8a469c3a74 view all404问题 2021-12-29 19:57:24 +08:00
Caiyanpeng 914e2719c1 Merge remote-tracking branch 'origin/dev_nonearth' into dev_cyp 2021-12-29 19:48:23 +08:00
Caiyanpeng 0fe5b3a953 微信分享问题解决 2021-12-29 19:48:15 +08:00
lishuo 088ab9a2b8 比赛分享标题&tcp微调 2021-12-29 19:06:00 +08:00
Caiyanpeng 816742898f Merge remote-tracking branch 'origin/dev_nonearth' into dev_cyp 2021-12-29 17:40:45 +08:00
lishuo 6055b2010b 分享问题修复 2021-12-29 17:39:55 +08:00
Caiyanpeng eab147c263 Merge remote-tracking branch 'origin/dev_nonearth' into dev_cyp 2021-12-29 17:22:51 +08:00
Caiyanpeng 0e16fec75a 图片模糊功能bug修改 2021-12-29 17:17:15 +08:00
lishuo eece0cffa5 Merge remote-tracking branch 'origin/dev_cyp' into dev_nonearth
# Conflicts:
#	Assets/Resources/UI/language.json
2021-12-29 17:07:34 +08:00
Caiyanpeng 95d845ac0f Merge remote-tracking branch 'origin/dev_nonearth' into dev_cyp 2021-12-29 17:06:04 +08:00
Caiyanpeng 8dde7520ad 修改细节 2021-12-29 17:05:58 +08:00
lishuo d4fa2bbb69 骑行保存数据改成同步 2021-12-29 17:05:07 +08:00
lishuo f3f17c1256 loading页面微调 2021-12-29 15:31:01 +08:00
Caiyanpeng be731c471b Merge remote-tracking branch 'origin/dev_nonearth' into dev_cyp 2021-12-29 14:51:27 +08:00
lishuo 7661a4e61d 全局缓存线路列表 2021-12-29 14:50:57 +08:00
Caiyanpeng 0ab425cb52 Merge remote-tracking branch 'origin/dev_nonearth' into dev_cyp
# Conflicts:
#	Assets/Resources/UI/language.json
2021-12-29 14:49:07 +08:00
lishuo b8a3a30629 骑行loading&赛事计时板调整 2021-12-29 14:40:58 +08:00
Caiyanpeng bac3334a01 修改细节 2021-12-29 14:23:37 +08:00
Caiyanpeng b3f6bb6861 Merge remote-tracking branch 'origin/dev_nonearth' into dev_cyp
# Conflicts:
#	Assets/Scripts/Scenes/Ride/Scripts/ResultPanelScript.cs
2021-12-28 18:26:56 +08:00
Caiyanpeng 3ca297ee96 按设计稿修改登录页登录样式;修改主页动画顺序;增加我的收藏列表可切换 2021-12-28 18:25:48 +08:00
lishuo 0500736fff 最近骑行继续骑数据源 2021-12-28 14:13:38 +08:00
Caiyanpeng f23fc4b4c0 Merge remote-tracking branch 'origin/dev_nonearth' into dev_cyp
# Conflicts:
#	Assets/Scenes/Login-Mobile.unity
#	Assets/Scripts/UI/Prefab/Panel/NewRouteDetailController.cs
2021-12-28 11:26:34 +08:00
lishuo 8e0ce907d0 分享调整 2021-12-28 11:25:35 +08:00
Caiyanpeng 2b390717c2 暂存 2021-12-28 11:25:09 +08:00
lishuo ffc98f1a58 骑行和赛事分享&集合正在骑行的人数 2021-12-27 18:29:23 +08:00
Caiyanpeng a2b44262f7 合计修正版本暂存 2021-12-27 09:39:07 +08:00
lishuo 2743c8d185 骑行界面优化&PCtips显示调整 2021-12-24 18:33:58 +08:00
Caiyanpeng 769b75e2e2 FB登录功能暂存;苹果有问题 2021-12-24 13:58:14 +08:00
Caiyanpeng 6423007638 Facebook sdk接入 2021-12-23 15:36:11 +08:00
Caiyanpeng 4260cf05d3 移动端浏览器 2021-12-23 09:54:14 +08:00
lishuo d91dc17ea7 单击手势进入极简模式 2021-12-22 16:20:27 +08:00
lishuo 67abc1ef63 loading页面不显示loading序列帧 2021-12-22 16:06:35 +08:00
lishuo fc55360be0 骑行视角手势&移除按钮音效 2021-12-22 14:25:57 +08:00
lishuo c8c27bd021 3d骑行视角旋转 2021-12-21 18:43:22 +08:00
Caiyanpeng 5c2c22b675 收藏问题;苹果登录无法快速登录问题 2021-12-21 17:41:17 +08:00
Caiyanpeng 4b3dad0b84 Merge remote-tracking branch 'origin/dev_nonearth' into dev_cyp
# Conflicts:
#	Assets/Scripts/Scenes/MainController.cs
2021-12-21 10:47:00 +08:00
lishuo 939084b074 解决消息处理bug 2021-12-21 10:10:05 +08:00
Caiyanpeng 05d2c74efa 苹果登录暂存 2021-12-21 09:58:07 +08:00
lishuo 348552b0bc 消息通知增加上线了 2021-12-20 14:44:48 +08:00
Caiyanpeng ebcc83ed6a Merge remote-tracking branch 'origin/dev_nonearth' into dev_cyp 2021-12-17 13:03:27 +08:00
Caiyanpeng a9e4b1fd34 安卓分享 2021-12-17 13:03:19 +08:00
lishuo 2c8457c75e 中断骑行弹窗bug修复 2021-12-17 11:24:24 +08:00
lishuo 7616e09a40 骑行loading页面bug修复&线路集合图片异步加载 2021-12-17 11:10:17 +08:00
Caiyanpeng 6c0d9f5dec Merge remote-tracking branch 'origin/dev_nonearth' into dev_cyp 2021-12-16 18:43:34 +08:00
Caiyanpeng 32777c739d 首页动画不停止bug;中文图片绑定 2021-12-16 18:43:26 +08:00
lishuo 77989384fc 音效微调 2021-12-16 18:27:50 +08:00
Caiyanpeng 12e0d8d295 Merge remote-tracking branch 'origin/dev_nonearth' into dev_cyp
# Conflicts:
#	Assets/Scripts/UI/Prefab/MapList/MapItem.cs
2021-12-16 16:55:14 +08:00
Caiyanpeng 1cb555c13d 移动端消息 2021-12-16 16:54:35 +08:00
lishuo b9d14a590c 音效&骑行loading优化 2021-12-16 16:53:38 +08:00
Caiyanpeng 24044ec772 跳上传线路网页;pc分两种消息弹窗 2021-12-16 16:00:14 +08:00
Caiyanpeng 603efc7508 三层消息通知,修改细节 2021-12-15 18:18:12 +08:00
Caiyanpeng 9231304269 Merge branch 'dev_nonearth' into dev_cyp 2021-12-15 13:32:38 +08:00
lishuo 40ac7e1397 消息通知 2021-12-15 13:24:26 +08:00
Caiyanpeng 98de46f8b1 Merge remote-tracking branch 'origin/dev_nonearth' into dev_cyp 2021-12-15 13:03:32 +08:00
Caiyanpeng 6ed3895fcd 加入合集后的跳转问题 2021-12-15 11:08:25 +08:00
Caiyanpeng ec4a28cd2a 集合首页和详情页 2021-12-14 18:10:58 +08:00
lishuo 3da24b200d Merge remote-tracking branch 'origin/dev_cyp' into dev_nonearth
# Conflicts:
#	Assets/Resources/UI/Prefab/Ride/Mobile/Panel.prefab
2021-12-14 16:24:09 +08:00
Caiyanpeng 16b42a19e4 ios端本地化 2021-12-13 17:18:57 +08:00
Caiyanpeng 625e2b7934 app名称本地化自适应;分享图片接入 2021-12-10 18:10:20 +08:00
Caiyanpeng cbd1ce3313 集合功能部分 2021-12-10 09:53:49 +08:00
lishuo 7d2af849f4 骑行视角等优化 2021-12-09 18:17:39 +08:00
lishuo b1fedd4831 骑行细节优化(视角缩放,海拔图拉伸) 2021-12-08 18:10:38 +08:00
lishuo 083b414be0 点击附近的人不隐藏面板 2021-12-07 17:43:32 +08:00
lishuo de4292d55a 骑行记录实时保存,异常中断重新连接 2021-12-07 16:44:36 +08:00
Caiyanpeng 542036fb45 Merge remote-tracking branch 'origin/dev_nonearth' into dev_cyp 2021-12-07 14:37:13 +08:00
Caiyanpeng fa144dbaa0 新页面框架(PC) 2021-12-07 14:37:08 +08:00
lishuo cc6730cbc4 汉化微调&赛事相关中文版本样式调整 2021-12-06 17:02:30 +08:00
lishuo aff636f9a8 Merge remote-tracking branch 'origin/dev_cyp' into dev_nonearth 2021-12-03 18:22:31 +08:00
Caiyanpeng ef3e3a8321 高版本反而弹更新的bug;部分手机自动更新由于程序退出导致安装包损坏问题 2021-12-03 18:21:17 +08:00
lishuo 5d8be079c2 汉化微调 2021-12-03 18:19:24 +08:00
Caiyanpeng aa0c8d4fb6 中文绑定一波 2021-11-25 17:31:26 +08:00
Caiyanpeng 134dc76ec5 Merge branch 'dev_language' into dev_release
# Conflicts:
#	Assets/Resources/UI/Prefab/Panel/Mobile/MapListPanel.prefab
#	Assets/Resources/UI/Prefab/Panel/Mobile/RaceListPanel.prefab
2021-11-25 10:04:35 +08:00
Caiyanpeng 9ff3de1d10 Merge branch 'dev_cyp' into dev_release 2021-11-25 10:03:35 +08:00
lishuo a2ff7604cc 解决海图索引超过2000头像不显示问题 2021-11-24 16:40:53 +08:00
lishuo 70a8bc0000 Merge remote-tracking branch 'origin/dev_release' into dev_release 2021-11-24 13:10:10 +08:00
lishuo 06b102f0eb 比赛海拔图位置&赛事无法开始问题 2021-11-24 13:08:42 +08:00
Caiyanpeng 350103d5a9 Merge remote-tracking branch 'origin/dev_release' into dev_release 2021-11-24 10:16:14 +08:00
Caiyanpeng 2cf77e94ed 搜索按钮变大 2021-11-24 10:16:09 +08:00
lishuo 917cbbfb90 赛事开始逻辑调整 2021-11-24 10:15:28 +08:00
Caiyanpeng eeffccd4e6 taskrun 2021-11-24 09:10:23 +08:00
lishuo 0549cdbd52 赛事提醒自动保存当前骑行 2021-11-23 16:27:35 +08:00
Caiyanpeng 732e5ac6c6 测试包;退出骑行场景释放tcp资源 2021-11-23 16:10:25 +08:00
Caiyanpeng c0ebe80a1f 网络异常处理 2021-11-23 15:58:02 +08:00
Caiyanpeng 23e5ae6ebd 中文调整 2021-11-23 15:48:22 +08:00
lishuo 265430053a 设备连接汉化调整 2021-11-23 09:58:55 +08:00
Caiyanpeng 190a66bb68 Merge branch 'dev_lishuo' into dev_cyp
# Conflicts:
#	Assets/Resources/UI/Prefab/Panel/Mobile/DevicePanel.prefab
#	Assets/Scenes/Login-Mobile.unity
#	Assets/Scenes/Login.unity
#	Assets/Scripts/App.cs
#	Assets/Scripts/Editor.meta
#	Assets/Scripts/Scenes/Ride/Scripts/CyclingController.cs
2021-11-23 09:51:10 +08:00
Caiyanpeng 8c5ad08475 比赛列表搜索逻辑统一 2021-11-23 09:47:04 +08:00
Caiyanpeng 6cc2486ebf Merge remote-tracking branch 'origin/ios_nearby' into dev_cyp 2021-11-23 09:34:20 +08:00
lishuo 68688c9daf 超时重连增加条件编译 2021-11-23 09:33:05 +08:00
lishuo d5ea26f15c ios附近的人掉线问题 2021-11-22 18:04:16 +08:00
Caiyanpeng 37e4c54c20 修改观察者模式提示连接设备bug;新版本设备连接bug;单开限定 2021-11-22 16:10:11 +08:00
Caiyanpeng 9570334e25 压缩图片bug解决 2021-11-22 09:51:17 +08:00
Caiyanpeng 3083224ee6 保存图片压缩;记录列表清缓存;ms延迟3s;比赛列表样式问题 2021-11-19 10:54:14 +08:00
Caiyanpeng 5ba176725f 单点登录不在进程内运行问题;gps取定位服务的;点击图标显示毫秒 2021-11-18 14:45:31 +08:00
Caiyanpeng 42e23e2f84 使用astc优化网络图片;workouts链接修改 2021-11-18 09:15:19 +08:00
Caiyanpeng 5480de5c6d 测试 2021-11-16 20:19:32 +08:00
Caiyanpeng e3e2f5200b Merge remote-tracking branch 'origin/dev_memory' into dev_cyp 2021-11-16 18:41:22 +08:00
Caiyanpeng 6a4390f1b9 两个列表进骑行释放内存 2021-11-16 18:41:18 +08:00
lishuo a73e125a49 骑行优化 2021-11-16 18:03:56 +08:00
Caiyanpeng 3295314b7e Merge remote-tracking branch 'origin/dev_memory' into dev_cyp 2021-11-15 15:21:46 +08:00
lishuo 8b3dd7a40a 骑行内存优化&设备连接点击优化 2021-11-15 15:21:22 +08:00
Caiyanpeng b79584f745 删除appcenter;删除打包后的debug 2021-11-15 11:38:13 +08:00
Caiyanpeng 402f19b8a5 Merge remote-tracking branch 'origin/dev_memory' into dev_cyp
# Conflicts:
#	Assets/Scenes/Login-Mobile.unity
#	Assets/Scenes/Login.unity
2021-11-15 11:34:49 +08:00
Caiyanpeng 9acde45f4a 一些设置调整;进入骑行时请texture 2021-11-15 11:33:57 +08:00
lishuo 004410048f Revert "Revert "骑行内存优化""
This reverts commit f7b29819f6.
2021-11-14 16:27:00 +08:00
lishuo f7b29819f6 Revert "骑行内存优化"
This reverts commit 7ebd5f59e3.
2021-11-14 16:25:41 +08:00
lishuo 7ebd5f59e3 骑行内存优化 2021-11-14 16:24:11 +08:00
lishuo e14a683f62 1478泰国时区问题 2021-11-12 16:53:45 +08:00
Caiyanpeng d754ff3b15 app center;增加發送ping的秒 2021-11-12 16:21:13 +08:00
lishuo 1bd1ffdb5a 重骑传参微调 2021-11-11 17:45:02 +08:00
lishuo c50c229e30 微调 2021-11-11 17:14:05 +08:00
lishuo 50b46c5b76 伴侣骑行继续骑 2021-11-11 15:55:58 +08:00
lishuo eb9338390c 多语言微调 2021-11-11 14:20:08 +08:00
lishuo 51834b709c 中文版本 2021-11-10 18:13:38 +08:00
Caiyanpeng 8e88b4adba 地球null问题,隐藏划船机 2021-11-09 16:47:21 +08:00
Caiyanpeng 609e4dc367 延迟问题解决 2021-11-09 11:37:10 +08:00
Caiyanpeng 9a545f00f4 修改细节 2021-11-08 13:07:08 +08:00
Caiyanpeng baab5a9fb0 修改细节 2021-11-03 13:48:53 +08:00
Caiyanpeng e8a12452ca Merge remote-tracking branch 'origin/dev_mobile_ble' into dev_release 2021-11-03 09:52:51 +08:00
Caiyanpeng f92b623349 暂存 2021-11-03 09:52:03 +08:00
lishuo a9fc25defb 解决大地球收藏问题&单人骑行切换地图海拔图位置问题和地图不全 2021-11-02 14:38:05 +08:00
Caiyanpeng 558fb16160 增加编号,loading页提示,延迟毫秒 2021-11-01 11:04:22 +08:00
Caiyanpeng b9aa0131cc 划船机保存前读秒 2021-10-25 16:13:04 +08:00
Caiyanpeng eb21914fb7 划船机其他细节 2021-10-22 18:18:26 +08:00
Caiyanpeng a4e17a56d0 划船机停止逻辑,切换图标 2021-10-21 18:04:33 +08:00
Caiyanpeng e503443f22 Merge branch 'dev_rower' into dev_release
# Conflicts:
#	Assets/Scenes/Login-Mobile.unity
2021-10-20 15:12:05 +08:00
Caiyanpeng 3a834fca08 ios审核先屏蔽第三方登录 2021-10-20 14:58:37 +08:00
Caiyanpeng 8f8ee0b833 android11跳转 2021-10-20 13:32:43 +08:00
Caiyanpeng 26e4e81402 暂存 2021-10-20 10:20:12 +08:00
Caiyanpeng b075279a14 增加搜索框,ios图片名重复问题 2021-10-18 14:03:26 +08:00
Caiyanpeng f731494396 pc兼容 2021-10-15 09:54:23 +08:00
Caiyanpeng dd4157cbc2 一些设置 2021-10-15 09:29:05 +08:00
Caiyanpeng 05f6c8a08b 微信注册样式问题 2021-10-14 14:04:44 +08:00
Caiyanpeng 3c540dece4 修改细节 2021-10-13 19:03:22 +08:00
Caiyanpeng d8adb8a5b8 Merge remote-tracking branch 'origin/dev_mobile_ble' into dev_release 2021-10-13 11:29:14 +08:00
Caiyanpeng 9be2e77ae5 设备连接页面检测定位服务 2021-10-13 11:29:09 +08:00
lishuo 0560d0f278 继续骑微调 2021-10-13 10:44:17 +08:00
Caiyanpeng efd1795e63 Merge remote-tracking branch 'origin/dev_mobile_ble' into dev_release 2021-10-12 20:51:07 +08:00
lishuo 4d404b9162 赛事观察者切换视角尾巴问题 2021-10-12 20:43:33 +08:00
Caiyanpeng f0314adb27 隐藏划船机 2021-10-12 20:26:41 +08:00
Caiyanpeng 2f0291836e ios以及bug处理 2021-10-12 20:26:25 +08:00
Caiyanpeng d4326ffb42 Merge remote-tracking branch 'origin/dev_mobile_ble' into dev_release 2021-10-12 20:11:18 +08:00
Caiyanpeng 44ff898f8d 更新弹窗 2021-10-12 20:07:13 +08:00
lishuo f3da1a5575 继续骑行隐藏右边影子选择面板 2021-10-12 15:26:58 +08:00
Caiyanpeng c19b8630cf 修改loading序列帧 2021-10-11 13:25:37 +08:00
Caiyanpeng 55d7304de1 pc打包错误 2021-10-09 15:05:41 +08:00
Caiyanpeng f1ddde8a2e Merge branch 'dev_mobile' into dev_gesture 2021-10-09 10:45:56 +08:00
Caiyanpeng cad2e92fd2 编辑页面手势应用 2021-10-09 10:42:27 +08:00
Caiyanpeng 4aa6178495 赛事卡片bug修正 2021-10-08 17:04:55 +08:00
Caiyanpeng fd8f419f09 手势插件引入暂存 2021-10-08 16:03:55 +08:00
Caiyanpeng 6d1bc8e2c8 暂存 2021-10-08 15:22:20 +08:00
1349 changed files with 212703 additions and 26481 deletions

No files matched your search

+2
View File
@@ -92,3 +92,5 @@ Assets/Mapbox/User.meta
Packages/packages-lock.json
GPUCache
Assets/Shatalmic/plugin.unitypackage.meta
.idea
Assets/AVProVideo
+130
View File
@@ -0,0 +1,130 @@
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public class AndroidUpdate : PFUIPanel
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
JObject data { get; set; }
public void StartDownload(JObject jo)
{
transform.Find("Panel/CurrentVersion").GetComponent<Text>().text = $"{App.GetLocalString("Current Version:")} {App.AppVersion}";
transform.Find("Panel/LastestVersion").GetComponent<Text>().text = $"{App.GetLocalString("Latest Version:")} {jo.Value<string>("Version")}";
data = jo;
var path = Application.temporaryCachePath + "/PowerFun.apk";
StartCoroutine(DownLoadExe(data.Value<string>("Url"), path, (p, isComplete) =>
{
transform.Find("Panel/Size").GetComponent<Text>().text = $"{App.GetLocalString("Downloaded")} {Math.Round(p * 100, 0)}%";// string.Format(, a, b);
transform.Find("Panel/Progress").GetComponent<Image>().fillAmount = (float)p;
if (isComplete)
{
PlayerPrefs.SetString("exeVersion", data.Value<string>("Version"));
new FileInfo(path + ".pfdownload").MoveTo(path);
OpenApk(path);
//Application.Quit();
}
}));
}
/*下载文件*/
IEnumerator DownLoadExe(string url, string desFileName, Action<double, bool> OnDownloadProgressEvent)
{
string version = data.Value<string>("Version");
if (File.Exists(desFileName))
{
//if(PlayerPrefs.GetString("exeVersion")==)
if (version == null)
{
yield break;
}
else
{
if (version == PlayerPrefs.GetString("exeVersion"))
{
OpenApk(desFileName);
//Application.Quit();
yield break;
}
else
{
File.Delete(desFileName);
}
}
//File.Delete(desFileName);
}
if (File.Exists(desFileName + ".pfdownload"))
{
File.Delete(desFileName + ".pfdownload");
}
using (var uwr = UnityWebRequest.Get(url))
{
var operation = uwr.SendWebRequest();
while (!operation.isDone)
{
/*
* as BugFinder metnioned in the comments
* what you want to track is uwr.downloadProgress
*/
var downloadDataProgress = uwr.downloadProgress * 100;
/*
* use a float division here
* I don't know what type downloadDataProgress is
* but if it is an int than you will always get
* an int division <somethingSmallerThan100>/100 = 0
*/
//progressBar.fillAmount = downloadDataProgress / 100.0f;
OnDownloadProgressEvent.Invoke(uwr.downloadProgress, false);
Debug.Log("Download: " + downloadDataProgress);
yield return null;
}
ByteArrayToFile(desFileName + ".pfdownload", uwr.downloadHandler.data);
OnDownloadProgressEvent.Invoke(1, true);
}
}
bool ByteArrayToFile(string fileName, byte[] byteArray)
{
try
{
using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
{
fs.Write(byteArray, 0, byteArray.Length);
return true;
}
}
catch (Exception ex)
{
Debug.LogError(ex);
return false;
}
}
void OpenApk(string path)
{
#if !UNITY_EDITOR
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
var activity = jc.GetStatic<AndroidJavaObject>("currentActivity");
//Debug.Log("打开apk"+ "file://" + path);
activity.Call("OpenApk", path);
//Application.Quit();
#endif
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ef1001f46abd4064a9837992f252bb97
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+159
View File
@@ -0,0 +1,159 @@
using Assets.Scripts;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class AppleInfoController : PFUIPanel
{
public Action afterClose = null;
private SignForm signForm;
private Dictionary<string, Selectable> signFormDict;
public bool startCaptcha = false;
protected override void Awake()
{
UIManager.AddEvent(transform.Find("FormContainer-Sign/btnClose").gameObject, UnityEngine.EventSystems.EventTriggerType.PointerClick, b =>
{
Close();
//if (afterClose != null)
//{
// afterClose.Invoke();
//}
});
signForm = new SignForm()
{
email = transform.Find("FormContainer-Sign/FirstPage/Email").GetComponent<InputField>(),
captcha = transform.Find("FormContainer-Sign/FirstPage/Captcha").GetComponent<InputField>(),
password = transform.Find("FormContainer-Sign/FirstPage/Password").GetComponent<InputField>(),
cpassword = transform.Find("FormContainer-Sign/FirstPage/CPassword").GetComponent<InputField>(),
};
signFormDict = new Dictionary<string, Selectable>
{
{ "Phone",signForm.email},
{ "Captcha",signForm.captcha},
{ "Pwd",signForm.password},
{ "CPwd",signForm.cpassword},
};
signPage1 = transform.Find("FormContainer-Sign/FirstPage");
UIManager.AddEvent(signPage1.Find("Captcha").Find("BtnGet").gameObject, UnityEngine.EventSystems.EventTriggerType.PointerClick, b =>
{
GetCaptcha();
});
UIManager.AddEvent(signPage1.Find("next").gameObject, UnityEngine.EventSystems.EventTriggerType.PointerClick, b =>
{
Submit();
});
}
private async void Submit()
{
if (signForm.password.text != signForm.cpassword.text)
{
Utils.SetValidate(signFormDict, JArray.FromObject(new object[]
{
new { Field="Pwd"},
new { Field="CPwd"},
}));
Utils.showToast(gameObject, "Two password entries are inconsistent");//两次密码输入不一致
return;
}
var res = await ConfigHelper.userApi.AppleCompleteInfo(signForm.email.text, signForm.captcha.text, signForm.password.text);
if (res.result)
{
Utils.showToast(null, App.GetLocalString("Success"), type: 1);
App.CurrentUser.Phone = signForm.email.text;
if (afterClose != null)
{
afterClose.Invoke();
}
Close();
}
else
{
Utils.SetValidate(signFormDict, JArray.FromObject(res.data));
Utils.showToast(null, res.errMsg);
}
}
float timer = 1f;
int time = 60;
Transform signPage1;
async void GetCaptcha()
{
var btn = signPage1.Find("Captcha").Find("BtnGet");
btn.GetComponent<Button>().enabled = false;
btn.GetComponent<Button>().interactable = false;
var btnText = btn.Find("Text").GetComponent<Text>();
var Email = signForm.email;
var r = await ConfigHelper.userApi.GetCaptcha(Email.text);
//Timer t = new Ti
if (r.result)
{
//if (r.data.Value<bool>("isExist"))
//{
// signPage1.Find("Password").gameObject.SetActive(false);
// signPage1.Find("CPassword").gameObject.SetActive(false);
//}
//else
//{
// signPage1.Find("Password").gameObject.SetActive(true);
// signPage1.Find("CPassword").gameObject.SetActive(true);
//}
time = 60;
btnText.text = $"Again({time})";
btn.GetComponent<Button>().enabled = false;
btn.GetComponent<Button>().interactable = false;
startCaptcha = true;
//timer.Interval = 1000;
//timer.AutoReset = true;
//timer.Elapsed += new ElapsedEventHandler(CaptchaTimerTick);
//timer.Enabled = true;
//btnGet.
}
else
{
btn.GetComponent<Button>().enabled = true;
btn.GetComponent<Button>().interactable = true;
Utils.showToast(gameObject, r.errMsg);
Utils.SetValidate(signFormDict, r.errFieldMsg);
}
}
void CaptchaTimerTick()
{
timer -= Time.deltaTime;
if (timer <= 0)
{
var btn = signPage1.Find("Captcha").Find("BtnGet");
var btnText = signPage1.Find("Captcha").Find("BtnGet").Find("Text").GetComponent<Text>();
btnText.text = $"{App.GetLocalString("Again")}({time--})";
if (time < 0)
{
btnText.text = App.GetLocalString("Get");
btn.GetComponent<Button>().enabled = true;
btn.GetComponent<Button>().interactable = true;
startCaptcha = false;
//timer.Stop();
}
timer += 1.0f;
}
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (startCaptcha)
{
CaptchaTimerTick();
}
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6a404dcc72dc4894c835c2097a5ad469
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+282
View File
@@ -0,0 +1,282 @@
using Assets.Scripts;
using Assets.Scripts.Apis.Models;
using DG.Tweening;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
public class BannerController : MonoBehaviour
{
// Start is called before the first frame update
private List<CanvasGroup> itemList;
private List<Vector3> standardPositions;
private List<Recommand> list;
private int currentIndex = 1;
private Dictionary<string, Texture> caches;
void Awake()
{
itemList = new List<CanvasGroup>
{
transform.Find("1").GetComponent<CanvasGroup>(),
transform.Find("2").GetComponent<CanvasGroup>(),
transform.Find("3").GetComponent<CanvasGroup>()
};
caches = new Dictionary<string, Texture>();
standardPositions = new List<Vector3>
{
transform.Find("1").localPosition,transform.Find("2").localPosition,transform.Find("3").localPosition
};
AddTouchEvent();
Debug.Log(standardPositions[0]);
Debug.Log(standardPositions[1]);
Debug.Log(standardPositions[2]);
}
TKPanRecognizer pan;
private void AddTouchEvent()
{
pan = new TKPanRecognizer();
var panList = new List<CanvasGroup>();
pan.gestureRecognizedEvent += (r) =>
{
if (!App.currentPageIsHome) return;
int center = GetCenterIndex(),
left = GetSideIndex(true),
right = GetSideIndex(false);
if (!(center == -1 || left == -1 || right == -1) && panList.Count == 0)
{
panList.Add(itemList[left]);
panList.Add(itemList[center]);
panList.Add(itemList[right]);
}
if (panList.Count == 0) return;
var startPoint = r.startTouchLocation();
if (((RectTransform)transform).isPointInTransfrom(startPoint))
{
foreach (var item in panList)
{
item.GetComponent<Button>().onClick.RemoveAllListeners();
}
var offset = pan.deltaTranslation;
if (panList[1].transform.localPosition.x == 0)
{
panList[1].transform.DOScale(0.8f, 0.5f);
}
if (offset.x > 0)
{
//-43 0 43
//后面的 如果往左,需要回到-43再往右
panList[0].transform.localPosition += new Vector3(1, 0, 0);
panList[1].transform.localPosition += new Vector3(1, 0, 0);
panList[2].transform.localPosition += new Vector3(-1, 0, 0);
}
else if (offset.x < 0)
{
panList[0].transform.localPosition += new Vector3(1, 0, 0);
panList[1].transform.localPosition += new Vector3(-1, 0, 0);
//后面的 如果往右,需要回到43再往左
panList[2].transform.localPosition += new Vector3(-1, 0, 0);
}
}
else
{
panList.Clear();
}
};
pan.gestureCompleteEvent += (r) =>
{
if (!App.currentPageIsHome) return;
if (panList.Count == 0) return;
if (panList[1].transform.localPosition.x < 0)
{
DOLeft(panList[0], panList[1], panList[2]);
}
else
{
DORight(panList[0], panList[1], panList[2]);
}
panList.Clear();
};
TouchKit.addGestureRecognizer(pan);
}
int sIndex = 0, eIndex = 2;
private void Start()
{
GetList();
}
async void GetList()
{
var res = await ConfigHelper.mapApi.GetRecommendList();
if (res.result)
{
if (res.data.Count >= 3)
{
sIndex = 0;eIndex = 2;
Initial(res.data);
gameObject.SetActive(true);
}
else
{
gameObject.SetActive(false);
}
}
}
public void Initial(List<Recommand> list)
{
int index = 0;
foreach (CanvasGroup c in itemList)
{
var area = list[index++];
c.GetComponent<RecommendController>().Initial(area, caches);
c.GetComponent<Button>().onClick.RemoveAllListeners();
if (c.alpha != 1)
{
if (c.transform.localPosition.x < 0)
{
c.GetComponent<Button>().onClick.AddListener(Right);
}
else
{
c.GetComponent<Button>().onClick.AddListener(Left);
}
}
else
{
c.GetComponent<Button>().onClick.AddListener(()=>GoDetail(c));
}
}
this.list = list;
}
bool animateLock = false;
private void Right()
{
int center = GetCenterIndex(),
left = GetSideIndex(true),
right = GetSideIndex(false);
if (center == -1 || left == -1 || right == -1 || animateLock) return;
animateLock = true;
if (leftse != null) leftse.Complete(true);
DORight(itemList[left], itemList[center], itemList[right]);
}
void DORight(CanvasGroup left, CanvasGroup center, CanvasGroup right)
{
Sequence se = DOTween.Sequence();
se.Join(center.DOFade(0.5f, 0.3f));
se.Join(center.GetComponent<RectTransform>().DOScale(Vector3.one * 0.8f, 0.3f));
se.Join(center.GetComponent<RectTransform>().DOLocalMoveX(offset, 0.3f));
se.Join(right.GetComponent<RectTransform>().DOLocalMoveX(-1* offset, 0.3f));
var area = list[((sIndex - 1) + list.Count) % list.Count];
sIndex--;
eIndex--;
if (sIndex < 0) sIndex = (sIndex + list.Count) % list.Count;
if (eIndex < 0) eIndex = (eIndex + list.Count) % list.Count;
Debug.Log($"{sIndex},{eIndex}");
right.GetComponent<RecommendController>().Initial(area, caches);
se.Join(left.DOFade(1, 0.3f));
se.Join(left.GetComponent<RectTransform>().DOScale(Vector3.one, 0.3f));
se.Join(left.GetComponent<RectTransform>().DOLocalMoveX(0, 0.3f));
se.Play().onComplete = ()=> { animateLock = false; };
rightse = se;
left.transform.SetAsLastSibling();
//事件改变
left.GetComponent<Button>().onClick.RemoveAllListeners();
left.GetComponent<Button>().onClick.AddListener(() => GoDetail(left));
center.GetComponent<Button>().onClick.RemoveAllListeners();
center.GetComponent<Button>().onClick.AddListener(Left);
right.GetComponent<Button>().onClick.RemoveAllListeners();
right.GetComponent<Button>().onClick.AddListener(Right);
}
#if UNITY_STANDALONE_WIN
float offset = 110;
#else
float offset = 43;
#endif
Sequence leftse, rightse;
private void Left()
{
int center = GetCenterIndex(),
left = GetSideIndex(true),
right = GetSideIndex(false);
if (center == -1 || left == -1 || right == -1|| animateLock) return;
animateLock = true;
if (rightse != null) rightse.Complete(true);
DOLeft(itemList[left], itemList[center], itemList[right]);
}
void DOLeft(CanvasGroup left, CanvasGroup center, CanvasGroup right)
{
Sequence se = DOTween.Sequence();
se.Join(center.DOFade(0.5f, 0.3f));
se.Join(center.GetComponent<RectTransform>().DOScale(Vector3.one * 0.8f, 0.3f));
se.Join(center.GetComponent<RectTransform>().DOLocalMoveX(-1* offset, 0.3f));
se.Join(left.GetComponent<RectTransform>().DOLocalMoveX(offset, 0.3f));
var area = list[((eIndex + 1) + list.Count) % list.Count];
sIndex++;
eIndex++;
if (sIndex >= list.Count - 1) sIndex = sIndex % list.Count;
if (eIndex >= list.Count - 1) eIndex = eIndex % list.Count;
Debug.Log($"{sIndex},{eIndex}");
var centerArea = list[currentIndex + 1];
left.GetComponent<RecommendController>().Initial(area, caches);
if (currentIndex < 0) currentIndex = list.Count - 1;
se.Join(right.DOFade(1, 0.3f));
se.Join(right.GetComponent<RectTransform>().DOScale(Vector3.one, 0.3f));
se.Join(right.GetComponent<RectTransform>().DOLocalMoveX(0, 0.3f));
se.Play().onComplete = () => { animateLock = false; };
leftse = se;
right.transform.SetAsLastSibling();
//事件改变
right.GetComponent<Button>().onClick.RemoveAllListeners();
right.GetComponent<Button>().onClick.AddListener(() => GoDetail(right));
center.GetComponent<Button>().onClick.RemoveAllListeners();
center.GetComponent<Button>().onClick.AddListener(Right);
left.GetComponent<Button>().onClick.RemoveAllListeners();
left.GetComponent<Button>().onClick.AddListener(Left);
}
int GetCenterIndex()
{
return itemList.FindIndex(x => x.transform.localPosition.x == 0);
}
int GetSideIndex(bool left)
{
return itemList.FindIndex(x => left ? x.transform.localPosition.x < 0 : x.transform.localPosition.x > 0);
}
void GoDetail(CanvasGroup c)
{
if (c.transform.localPosition.x == 0)
{
var se = DOTween.Sequence();
se.Append(c.transform.DOScale(1.05f * Vector3.one, 0.15f));
se.Append(c.transform.DOScale(1f * Vector3.one, 0.15f));
se.Play().onComplete = ()=>
{
c.GetComponent<RecommendController>().DoWithType();
};
}
}
float autoTime = 5;
// Update is called once per frame
void Update()
{
autoTime -= Time.deltaTime;
if (autoTime < 0)
{
Left();
autoTime += 5;
}
}
private void OnDestroy()
{
Debug.Log(248+"毁灭");
TouchKit.removeGestureRecognizer(pan);
caches = null;
Resources.UnloadUnusedAssets();
GC.Collect();
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 99085319355aa0f44a5db27b26f6ec95
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -10,7 +10,7 @@ using UnityEngine;
namespace Assets
{
[CustomEditor(typeof(RadarChart), true)]
class RadarChartInspector : Editor
class RadarChartInspector : UnityEditor.Editor
{
bool mCategories = false;
bool mGroups = false;
@@ -7,7 +7,7 @@ using UnityEngine;
namespace ChartAndGraph
{
[Serializable ]
[Serializable]
public struct DoubleVector2
{
public double x, y;
@@ -565,6 +565,23 @@ namespace ChartAndGraph
return true;
}
public int GetViewIndex(int dataIndex,string category)
{
CategoryData data = (CategoryData)mData[category];
int viewIndex = 0;
List<DoubleVector3> points = data.getPoints();
if (points.Count == 0)
viewIndex = 0;
if (dataIndex < 0)
viewIndex = 0;
for (int i = 0; i < points.Count; i++)
{
if (points[i].x == dataIndex)
viewIndex = i;
}
return viewIndex;
}
public DoubleVector3 GetPoint(string category, int index)
{
CategoryData data = (CategoryData)mData[category];
+2 -1
View File
@@ -33,9 +33,10 @@ public class CountDownAnimation : PFUIPanel
return;
}
var flag = int.TryParse(s,out int a);
Debug.Log(a);
if (flag)
{
if (a == 1 && action2 != null)
if (a == 1 && action2 != null)
{
action2.Invoke();
}
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a5024d7258021714e832782d73a13749
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 85d4f615e53b346478ff4dff569a317f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,9 @@
/*
InfoPlist.strings
IosToRN
Created by lishuo on 2021/2/24.
*/
"CFBundleName"="PowerFun";
"CFBundleDisplayName"="PowerFun";
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: a4aa11356c3e11a41941fc03fae3a26b
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cde742ac5daeb784ca7837d4e2622f26
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,9 @@
/*
InfoPlist.strings
IosToRN
Created by lishuo on 2021/2/24.
*/
"CFBundleName"="运动地球";
"CFBundleDisplayName"="运动地球";
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d407327a982cae2468c2e1c372b5dbd3
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+77
View File
@@ -0,0 +1,77 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
using ChillyRoom.UnityEditor.iOS.Xcode;
namespace Assets
{
public class NativeLocale
{
public static void AddLocalizedStringsIOS(string projectPath, string localizedDirectoryPath)
{
DirectoryInfo dir = new DirectoryInfo(localizedDirectoryPath);
if (!dir.Exists)
return;
List<string> locales = new List<string>();
var localeDirs = dir.GetDirectories("*.lproj", SearchOption.TopDirectoryOnly);
foreach (var sub in localeDirs)
locales.Add(Path.GetFileNameWithoutExtension(sub.Name));
AddLocalizedStringsIOS(projectPath, localizedDirectoryPath, locales);
}
public static void AddLocalizedStringsIOS(string projectPath, string localizedDirectoryPath, List<string> validLocales)
{
string projPath = projectPath + "/Unity-iPhone.xcodeproj/project.pbxproj";
PBXProject proj = new PBXProject();
proj.ReadFromFile(projPath);
foreach (var locale in validLocales)
{
// copy contents in the localization directory to project directory
string src = Path.Combine(localizedDirectoryPath, locale + ".lproj");
DirectoryCopy(src, Path.Combine(projectPath, "Unity-iPhone/" + locale + ".lproj"));
string fileRelatvePath = string.Format("Unity-iPhone/{0}.lproj/InfoPlist.strings", locale);
proj.AddLocalization("Localizable.strings", locale, fileRelatvePath);
}
proj.WriteToFile(projPath);
}
private static void DirectoryCopy(string sourceDirName, string destDirName)
{
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
if (!dir.Exists)
return;
if (!Directory.Exists(destDirName))
{
Directory.CreateDirectory(destDirName);
}
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
// skip unity meta files
if (file.FullName.EndsWith(".meta"))
continue;
string temppath = Path.Combine(destDirName, file.Name);
file.CopyTo(temppath, false);
}
DirectoryInfo[] dirs = dir.GetDirectories();
foreach (DirectoryInfo subdir in dirs)
{
string temppath = Path.Combine(destDirName, subdir.Name);
DirectoryCopy(subdir.FullName, temppath);
}
}
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 04d272fbec5a52a4a8a1bb6b201a3030
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cbfad999c612c244f9a6c609a97122ca
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+20
View File
@@ -0,0 +1,20 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a403a09e241a0480a957591ea60fb785, type: 3}
m_Name: settings
m_EditorClassIdentifier:
usesCleartextTraffic: 1
writeExternalStorage: 0
accessFineLocation: 0
addsKotlin: 1
addsAndroidBrowser: 1
enableJetifier: 1
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 580a44b4404956543a86c106381eae18
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
+42 -7
View File
@@ -5,6 +5,8 @@ using System.IO;
using UnityEngine;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;
using System;
#endif
public static class XCodePostProcessBuild
@@ -14,7 +16,7 @@ public static class XCodePostProcessBuild
"Security.framework","WebKit.framework", "CoreGraphics.framework"
};
[PostProcessBuild(1)]
[PostProcessBuild(11)]
public static void OnPostprocessBuild(BuildTarget buildTarget, string pathToBuiltProject)
{
if (BuildTarget.iOS != buildTarget)
@@ -23,8 +25,25 @@ public static class XCodePostProcessBuild
}
string projectPath = pathToBuiltProject + "/Unity-iPhone.xcodeproj/project.pbxproj";
SetFrameworksAndBuildSettings(projectPath);
AddGooglePlist(pathToBuiltProject,projectPath);
SetInfoList(pathToBuiltProject, "com.ZhiXingPai.PowerFun", "wxe3573a84e7e29902");
SetAssociatedDomains(projectPath, "wx.powerfun.com.cn");
Assets.NativeLocale.AddLocalizedStringsIOS(pathToBuiltProject, Path.Combine(Application.dataPath, "Editor/Locale"));
}
private static void AddGooglePlist(string pathToBuiltProject,string path)
{
PBXProject proj = new PBXProject();
proj.ReadFromString(File.ReadAllText(path));
// This is the Xcode target in the generated project
string target = proj.GetUnityMainTargetGuid();
// Copy plist from the project folder to the build folder
FileUtil.CopyFileOrDirectory("Assets/Plugins/iOS/GoogleService-Info.plist", pathToBuiltProject + "/GoogleService-Info.plist");
proj.AddFileToBuild(target, proj.AddFile("GoogleService-Info.plist", "GoogleService-Info.plist"));
// Write PBXProject object back to the file
proj.WriteToFile(path);
}
private static void SetFrameworksAndBuildSettings(string path)
@@ -37,6 +56,7 @@ public static class XCodePostProcessBuild
proj.AddBuildProperty(target, "Other Linker Flags", "-Objc -all_load");
proj.SetBuildProperty(target, "ENABLE_BITCODE", "NO");
//根据微信SDK文档的要求,加入相关的Frameworks
for (int i = 0; i < csAddFrameworks.Length; ++i)
{
@@ -44,6 +64,14 @@ public static class XCodePostProcessBuild
proj.AddFrameworkToProject(target, csAddFrameworks[i], false);
}
//苹果登录配置项
//proj.AddCapability(target, PBXCapabilityType.SignInWithApple);
proj.AddFrameworkToProject(proj.GetUnityFrameworkTargetGuid(), "AuthenticationServices.framework", false);
//移除无用配置项
proj.RemoveFrameworkFromProject(proj.GetUnityFrameworkTargetGuid(), "Chromium Embedded Framework.framework");
proj.SetBuildProperty(proj.ProjectGuid(), "ENABLE_BITCODE", "NO");
proj.SetBuildProperty(proj.ProjectGuid(), "CLANG_ENABLE_MODULES", "YES");
File.WriteAllText(path, proj.WriteToString());
}
@@ -60,12 +88,19 @@ public static class XCodePostProcessBuild
dict.SetString("CFBundleURLName", wxUrlName);
PlistElementArray urlSchemes = dict.CreateArray("CFBundleURLSchemes");
urlSchemes.AddString(wxScheme);
PlistElementDict dictMine = urlArray.AddDict();
dictMine.SetString("CFBundleTypeRole", "Editor");
dictMine.SetString("CFBundleURLName", "powerfunx");
PlistElementArray urlSchemesMine = dictMine.CreateArray("CFBundleURLSchemes");
urlSchemesMine.AddString("powerfunx");
PlistElementDict dictGG = urlArray.AddDict();
dictGG.SetString("CFBundleTypeRole", "Editor");
dictGG.SetString("CFBundleURLName", "google");
PlistElementArray urlSchemesGG = dictGG.CreateArray("CFBundleURLSchemes");
urlSchemesGG.AddString("com.googleusercontent.apps.492440200766-spo9287smn7epmlarib2pek9kficsq86");
// 在 “info”标签栏的“LSApplicationQueriesSchemes“添加weixin wechat和weixinULAPI
PlistElementArray wxArray = plist.root.CreateArray("LSApplicationQueriesSchemes");
wxArray.AddString("weixin");
@@ -79,11 +114,9 @@ public static class XCodePostProcessBuild
PlistElementDict qxLoc = plist.root.CreateDict("NSLocationWhenInUseUsageDescription");
qxLoc.SetBoolean("NSLocationWhenInUseUsageDescription", true);
plist.root.SetString("NSCameraUsageDescription","cameraDesciption");
plist.root.SetString("NSContactsUsageDescription", "contactsDesciption");
plist.root.SetString("NSMicrophoneUsageDescription", "microphoneDesciption");
plist.root.SetString("NSPhotoLibraryUsageDescription", "photoLibraryDesciption");
plist.root.SetString("NSLocationWhenInUseUsageDescription", "locationWhenInUseUsageDescription");
plist.root.SetString("NSCameraUsageDescription","Use the camera to scan the QR code or take a photo or take a video to upload.");
plist.root.SetString("NSPhotoLibraryUsageDescription", "Need to access your image file to upload.");
plist.root.SetString("NSLocationWhenInUseUsageDescription", "Need to get your geographic location in order to push the route for you.");
plist.root.SetBoolean("ITSAppUsesNonExemptEncryption", false);
File.WriteAllText(listPath, plist.WriteToString());
}
@@ -98,7 +131,9 @@ public static class XCodePostProcessBuild
var entitlements = new ProjectCapabilityManager(pbxProjectPath, entitlementsFileName, targetName);
entitlements.AddAssociatedDomains(new string[] { "applinks:" + domainUrl });
//苹果登录
entitlements.AddSignInWithApple();
entitlements.AddPushNotifications(false);
entitlements.WriteToFile();
}
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a9b05453b42e5aa40b0b080cdec35b95
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+813
View File
@@ -0,0 +1,813 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace ChillyRoom.UnityEditor.iOS.Xcode
{
internal class DeviceTypeRequirement
{
public static readonly string Key = "idiom";
public static readonly string Any = "universal";
public static readonly string iPhone = "iphone";
public static readonly string iPad = "ipad";
public static readonly string Mac = "mac";
public static readonly string iWatch = "watch";
}
internal class MemoryRequirement
{
public static readonly string Key = "memory";
public static readonly string Any = "";
public static readonly string Mem1GB = "1GB";
public static readonly string Mem2GB = "2GB";
}
internal class GraphicsRequirement
{
public static readonly string Key = "graphics-feature-set";
public static readonly string Any = "";
public static readonly string Metal1v2 = "metal1v2";
public static readonly string Metal2v2 = "metal2v2";
}
// only used for image sets
internal class SizeClassRequirement
{
public static readonly string HeightKey = "height-class";
public static readonly string WidthKey = "width-class";
public static readonly string Any = "";
public static readonly string Compact = "compact";
public static readonly string Regular = "regular";
}
// only used for image sets
internal class ScaleRequirement
{
public static readonly string Key = "scale";
public static readonly string Any = ""; // vector image
public static readonly string X1 = "1x";
public static readonly string X2 = "2x";
public static readonly string X3 = "3x";
}
internal class DeviceRequirement
{
internal Dictionary<string, string> values = new Dictionary<string, string>();
public DeviceRequirement AddDevice(string device)
{
AddCustom(DeviceTypeRequirement.Key, device);
return this;
}
public DeviceRequirement AddMemory(string memory)
{
AddCustom(MemoryRequirement.Key, memory);
return this;
}
public DeviceRequirement AddGraphics(string graphics)
{
AddCustom(GraphicsRequirement.Key, graphics);
return this;
}
public DeviceRequirement AddWidthClass(string sizeClass)
{
AddCustom(SizeClassRequirement.WidthKey, sizeClass);
return this;
}
public DeviceRequirement AddHeightClass(string sizeClass)
{
AddCustom(SizeClassRequirement.HeightKey, sizeClass);
return this;
}
public DeviceRequirement AddScale(string scale)
{
AddCustom(ScaleRequirement.Key, scale);
return this;
}
public DeviceRequirement AddCustom(string key, string value)
{
if (values.ContainsKey(key))
values.Remove(key);
values.Add(key, value);
return this;
}
public DeviceRequirement()
{
values.Add("idiom", DeviceTypeRequirement.Any);
}
}
internal class AssetCatalog
{
AssetFolder m_Root;
public string path { get { return m_Root.path; } }
public AssetFolder root { get { return m_Root; } }
public AssetCatalog(string path, string authorId)
{
if (Path.GetExtension(path) != ".xcassets")
throw new Exception("Asset catalogs must have xcassets extension");
m_Root = new AssetFolder(path, null, authorId);
}
AssetFolder OpenFolderForResource(string relativePath)
{
var pathItems = PBXPath.Split(relativePath).ToList();
// remove path filename
pathItems.RemoveAt(pathItems.Count - 1);
AssetFolder folder = root;
foreach (var pathItem in pathItems)
folder = folder.OpenFolder(pathItem);
return folder;
}
// Checks if a dataset at the given path exists and returns it if it does.
// Otherwise, creates a new dataset. Parent folders are created if needed.
// Note: the path is filesystem path, not logical asset name formed
// only from names of the folders that have "provides namespace" attribute.
// If you want to put certain resources in folders with namespace, first
// manually create the folders and then set the providesNamespace attribute.
// OpenNamespacedFolder may help to do this.
public AssetDataSet OpenDataSet(string relativePath)
{
var folder = OpenFolderForResource(relativePath);
return folder.OpenDataSet(Path.GetFileName(relativePath));
}
public AssetImageSet OpenImageSet(string relativePath)
{
var folder = OpenFolderForResource(relativePath);
return folder.OpenImageSet(Path.GetFileName(relativePath));
}
public AssetImageStack OpenImageStack(string relativePath)
{
var folder = OpenFolderForResource(relativePath);
return folder.OpenImageStack(Path.GetFileName(relativePath));
}
public AssetBrandAssetGroup OpenBrandAssetGroup(string relativePath)
{
var folder = OpenFolderForResource(relativePath);
return folder.OpenBrandAssetGroup(Path.GetFileName(relativePath));
}
// Checks if a folder with given path exists and returns it if it does.
// Otherwise, creates a new folder. Parent folders are created if needed.
public AssetFolder OpenFolder(string relativePath)
{
if (relativePath == null)
return root;
var pathItems = PBXPath.Split(relativePath);
if (pathItems.Length == 0)
return root;
AssetFolder folder = root;
foreach (var pathItem in pathItems)
folder = folder.OpenFolder(pathItem);
return folder;
}
// Creates a directory structure with "provides namespace" attribute.
// First, retrieves or creates the directory at relativeBasePath, creating parent
// directories if needed. Effectively calls OpenFolder(relativeBasePath).
// Then, relative to this directory, creates namespacePath directories with "provides
// namespace" attribute set. Fails if the attribute can't be set.
public AssetFolder OpenNamespacedFolder(string relativeBasePath, string namespacePath)
{
var folder = OpenFolder(relativeBasePath);
var pathItems = PBXPath.Split(namespacePath);
foreach (var pathItem in pathItems)
{
folder = folder.OpenFolder(pathItem);
folder.providesNamespace = true;
}
return folder;
}
public void Write()
{
Write(null);
}
public void Write(List<string> warnings)
{
m_Root.Write(warnings);
}
}
internal abstract class AssetCatalogItem
{
public readonly string name;
public readonly string authorId;
public string path { get { return m_Path; } }
protected Dictionary<string, string> m_Properties = new Dictionary<string, string>();
protected string m_Path;
public AssetCatalogItem(string name, string authorId)
{
if (name != null && name.Contains("/"))
throw new Exception("Asset catalog item must not have slashes in name");
this.name = name;
this.authorId = authorId;
}
protected JsonElementDict WriteInfoToJson(JsonDocument doc)
{
var info = doc.root.CreateDict("info");
info.SetInteger("version", 1);
info.SetString("author", authorId);
return info;
}
public abstract void Write(List<string> warnings);
}
internal class AssetFolder : AssetCatalogItem
{
List<AssetCatalogItem> m_Items = new List<AssetCatalogItem>();
bool m_ProvidesNamespace = false;
public bool providesNamespace
{
get { return m_ProvidesNamespace; }
set {
if (m_Items.Count > 0 && value != m_ProvidesNamespace)
throw new Exception("Asset folder namespace providing status can't be "+
"changed after items have been added");
m_ProvidesNamespace = value;
}
}
internal AssetFolder(string parentPath, string name, string authorId) : base(name, authorId)
{
if (name != null)
m_Path = Path.Combine(parentPath, name);
else
m_Path = parentPath;
}
// Checks if a folder with given name exists and returns it if it does.
// Otherwise, creates a new folder.
public AssetFolder OpenFolder(string name)
{
var item = GetChild(name);
if (item != null)
{
if (item is AssetFolder)
return item as AssetFolder;
throw new Exception("The given path is already occupied with an asset");
}
var folder = new AssetFolder(m_Path, name, authorId);
m_Items.Add(folder);
return folder;
}
T GetExistingItemWithType<T>(string name) where T : class
{
var item = GetChild(name);
if (item != null)
{
if (item is T)
return item as T;
throw new Exception("The given path is already occupied with an asset");
}
return null;
}
// Checks if a dataset with given name exists and returns it if it does.
// Otherwise, creates a new data set.
public AssetDataSet OpenDataSet(string name)
{
var item = GetExistingItemWithType<AssetDataSet>(name);
if (item != null)
return item;
var dataset = new AssetDataSet(m_Path, name, authorId);
m_Items.Add(dataset);
return dataset;
}
// Checks if an imageset with given name exists and returns it if it does.
// Otherwise, creates a new image set.
public AssetImageSet OpenImageSet(string name)
{
var item = GetExistingItemWithType<AssetImageSet>(name);
if (item != null)
return item;
var imageset = new AssetImageSet(m_Path, name, authorId);
m_Items.Add(imageset);
return imageset;
}
// Checks if a image stack with given name exists and returns it if it does.
// Otherwise, creates a new image stack.
public AssetImageStack OpenImageStack(string name)
{
var item = GetExistingItemWithType<AssetImageStack>(name);
if (item != null)
return item;
var imageStack = new AssetImageStack(m_Path, name, authorId);
m_Items.Add(imageStack);
return imageStack;
}
// Checks if a brand asset with given name exists and returns it if it does.
// Otherwise, creates a new brand asset.
public AssetBrandAssetGroup OpenBrandAssetGroup(string name)
{
var item = GetExistingItemWithType<AssetBrandAssetGroup>(name);
if (item != null)
return item;
var brandAsset = new AssetBrandAssetGroup(m_Path, name, authorId);
m_Items.Add(brandAsset);
return brandAsset;
}
// Returns the requested item or null if not found
public AssetCatalogItem GetChild(string name)
{
foreach (var item in m_Items)
{
if (item.name == name)
return item;
}
return null;
}
void WriteJson()
{
if (!providesNamespace)
return; // json is optional when namespace is not provided
var doc = new JsonDocument();
WriteInfoToJson(doc);
var props = doc.root.CreateDict("properties");
props.SetBoolean("provides-namespace", providesNamespace);
doc.WriteToFile(Path.Combine(m_Path, "Contents.json"));
}
public override void Write(List<string> warnings)
{
if (Directory.Exists(m_Path))
Directory.Delete(m_Path, true); // ensure we start from clean state
Directory.CreateDirectory(m_Path);
WriteJson();
foreach (var item in m_Items)
item.Write(warnings);
}
}
abstract class AssetCatalogItemWithVariants : AssetCatalogItem
{
protected List<VariantData> m_Variants = new List<VariantData>();
protected List<string> m_ODRTags = new List<string>();
protected AssetCatalogItemWithVariants(string name, string authorId) :
base(name, authorId)
{
}
protected class VariantData
{
public DeviceRequirement requirement;
public string path;
public VariantData(DeviceRequirement requirement, string path)
{
this.requirement = requirement;
this.path = path;
}
}
public bool HasVariant(DeviceRequirement requirement)
{
foreach (var item in m_Variants)
{
if (item.requirement.values == requirement.values)
return true;
}
return false;
}
public void AddOnDemandResourceTag(string tag)
{
if (!m_ODRTags.Contains(tag))
m_ODRTags.Add(tag);
}
protected void AddVariant(VariantData newItem)
{
foreach (var item in m_Variants)
{
if (item.requirement.values == newItem.requirement.values)
throw new Exception("The given requirement has been already added");
if (Path.GetFileName(item.path) == Path.GetFileName(path))
throw new Exception("Two items within the same set must not have the same file name");
}
if (Path.GetFileName(newItem.path) == "Contents.json")
throw new Exception("The file name must not be equal to Contents.json");
m_Variants.Add(newItem);
}
protected void WriteODRTagsToJson(JsonElementDict info)
{
if (m_ODRTags.Count > 0)
{
var tags = info.CreateArray("on-demand-resource-tags");
foreach (var tag in m_ODRTags)
tags.AddString(tag);
}
}
protected void WriteRequirementsToJson(JsonElementDict item, DeviceRequirement req)
{
foreach (var kv in req.values)
{
if (kv.Value != null && kv.Value != "")
item.SetString(kv.Key, kv.Value);
}
}
}
internal class AssetDataSet : AssetCatalogItemWithVariants
{
class DataSetVariant : VariantData
{
public string id;
public DataSetVariant(DeviceRequirement requirement, string path, string id) : base(requirement, path)
{
this.id = id;
}
}
internal AssetDataSet(string parentPath, string name, string authorId) : base(name, authorId)
{
m_Path = Path.Combine(parentPath, name + ".dataset");
}
// an exception is thrown is two equivalent requirements are added.
// The same asset dataset must not have paths with equivalent filenames.
// The identifier allows to identify which data variant is actually loaded (use
// the typeIdentifer property of the NSDataAsset that was created from the data set)
public void AddVariant(DeviceRequirement requirement, string path, string typeIdentifier)
{
foreach (DataSetVariant item in m_Variants)
{
if (item.id != null && typeIdentifier != null && item.id == typeIdentifier)
throw new Exception("Two items within the same dataset must not have the same id");
}
AddVariant(new DataSetVariant(requirement, path, typeIdentifier));
}
public override void Write(List<string> warnings)
{
Directory.CreateDirectory(m_Path);
var doc = new JsonDocument();
var info = WriteInfoToJson(doc);
WriteODRTagsToJson(info);
var data = doc.root.CreateArray("data");
foreach (DataSetVariant item in m_Variants)
{
var filename = Path.GetFileName(item.path);
if (!File.Exists(item.path))
{
if (warnings != null)
warnings.Add("File not found: " + item.path);
}
else
File.Copy(item.path, Path.Combine(m_Path, filename));
var docItem = data.AddDict();
docItem.SetString("filename", filename);
WriteRequirementsToJson(docItem, item.requirement);
if (item.id != null)
docItem.SetString("universal-type-identifier", item.id);
}
doc.WriteToFile(Path.Combine(m_Path, "Contents.json"));
}
}
internal class ImageAlignment
{
public int left = 0, right = 0, top = 0, bottom = 0;
}
internal class ImageResizing
{
public enum SlicingType
{
Horizontal,
Vertical,
HorizontalAndVertical
}
public enum ResizeMode
{
Stretch,
Tile
}
public SlicingType type = SlicingType.HorizontalAndVertical;
public int left = 0; // only valid for horizontal slicing
public int right = 0; // only valid for horizontal slicing
public int top = 0; // only valid for vertical slicing
public int bottom = 0; // only valid for vertical slicing
public ResizeMode centerResizeMode = ResizeMode.Stretch;
public int centerWidth = 0; // only valid for vertical slicing
public int centerHeight = 0; // only valid for horizontal slicing
}
// TODO: rendering intent property
internal class AssetImageSet : AssetCatalogItemWithVariants
{
internal AssetImageSet(string assetCatalogPath, string name, string authorId) : base(name, authorId)
{
m_Path = Path.Combine(assetCatalogPath, name + ".imageset");
}
class ImageSetVariant : VariantData
{
public ImageAlignment alignment = null;
public ImageResizing resizing = null;
public ImageSetVariant(DeviceRequirement requirement, string path) : base(requirement, path)
{
}
}
public void AddVariant(DeviceRequirement requirement, string path)
{
AddVariant(new ImageSetVariant(requirement, path));
}
public void AddVariant(DeviceRequirement requirement, string path, ImageAlignment alignment, ImageResizing resizing)
{
var imageset = new ImageSetVariant(requirement, path);
imageset.alignment = alignment;
imageset.resizing = resizing;
AddVariant(imageset);
}
void WriteAlignmentToJson(JsonElementDict item, ImageAlignment alignment)
{
var docAlignment = item.CreateDict("alignment-insets");
docAlignment.SetInteger("top", alignment.top);
docAlignment.SetInteger("bottom", alignment.bottom);
docAlignment.SetInteger("left", alignment.left);
docAlignment.SetInteger("right", alignment.right);
}
static string GetSlicingMode(ImageResizing.SlicingType mode)
{
switch (mode)
{
case ImageResizing.SlicingType.Horizontal: return "3-part-horizontal";
case ImageResizing.SlicingType.Vertical: return "3-part-vertical";
case ImageResizing.SlicingType.HorizontalAndVertical: return "9-part";
}
return "";
}
static string GetCenterResizeMode(ImageResizing.ResizeMode mode)
{
switch (mode)
{
case ImageResizing.ResizeMode.Stretch: return "stretch";
case ImageResizing.ResizeMode.Tile: return "tile";
}
return "";
}
void WriteResizingToJson(JsonElementDict item, ImageResizing resizing)
{
var docResizing = item.CreateDict("resizing");
docResizing.SetString("mode", GetSlicingMode(resizing.type));
var docCenter = docResizing.CreateDict("center");
docCenter.SetString("mode", GetCenterResizeMode(resizing.centerResizeMode));
docCenter.SetInteger("width", resizing.centerWidth);
docCenter.SetInteger("height", resizing.centerHeight);
var docInsets = docResizing.CreateDict("cap-insets");
docInsets.SetInteger("top", resizing.top);
docInsets.SetInteger("bottom", resizing.bottom);
docInsets.SetInteger("left", resizing.left);
docInsets.SetInteger("right", resizing.right);
}
public override void Write(List<string> warnings)
{
Directory.CreateDirectory(m_Path);
var doc = new JsonDocument();
var info = WriteInfoToJson(doc);
WriteODRTagsToJson(info);
var images = doc.root.CreateArray("images");
foreach (ImageSetVariant item in m_Variants)
{
var filename = Path.GetFileName(item.path);
if (!File.Exists(item.path))
{
if (warnings != null)
warnings.Add("File not found: " + item.path);
}
else
File.Copy(item.path, Path.Combine(m_Path, filename));
var docItem = images.AddDict();
docItem.SetString("filename", filename);
WriteRequirementsToJson(docItem, item.requirement);
if (item.alignment != null)
WriteAlignmentToJson(docItem, item.alignment);
if (item.resizing != null)
WriteResizingToJson(docItem, item.resizing);
}
doc.WriteToFile(Path.Combine(m_Path, "Contents.json"));
}
}
/* A stack layer may either contain an image set or reference another imageset
*/
class AssetImageStackLayer : AssetCatalogItem
{
internal AssetImageStackLayer(string assetCatalogPath, string name, string authorId) : base(name, authorId)
{
m_Path = Path.Combine(assetCatalogPath, name + ".imagestacklayer");
m_Imageset = new AssetImageSet(m_Path, "Content", authorId);
}
AssetImageSet m_Imageset = null;
string m_ReferencedName = null;
public void SetReference(string name)
{
m_Imageset = null;
m_ReferencedName = name;
}
public string ReferencedName()
{
return m_ReferencedName;
}
public AssetImageSet GetImageSet()
{
return m_Imageset;
}
public override void Write(List<string> warnings)
{
Directory.CreateDirectory(m_Path);
var doc = new JsonDocument();
WriteInfoToJson(doc);
if (m_ReferencedName != null)
{
var props = doc.root.CreateDict("properties");
var reference = props.CreateDict("content-reference");
reference.SetString("type", "image-set");
reference.SetString("name", m_ReferencedName);
reference.SetString("matching-style", "fully-qualified-name");
}
if (m_Imageset != null)
m_Imageset.Write(warnings);
doc.WriteToFile(Path.Combine(m_Path, "Contents.json"));
}
}
class AssetImageStack : AssetCatalogItem
{
List<AssetImageStackLayer> m_Layers = new List<AssetImageStackLayer>();
internal AssetImageStack(string assetCatalogPath, string name, string authorId) : base(name, authorId)
{
m_Path = Path.Combine(assetCatalogPath, name + ".imagestack");
}
public AssetImageStackLayer AddLayer(string name)
{
foreach (var layer in m_Layers)
{
if (layer.name == name)
throw new Exception("A layer with given name already exists");
}
var newLayer = new AssetImageStackLayer(m_Path, name, authorId);
m_Layers.Add(newLayer);
return newLayer;
}
public override void Write(List<string> warnings)
{
Directory.CreateDirectory(m_Path);
var doc = new JsonDocument();
WriteInfoToJson(doc);
var docLayers = doc.root.CreateArray("layers");
foreach (var layer in m_Layers)
{
layer.Write(warnings);
var docLayer = docLayers.AddDict();
docLayer.SetString("filename", Path.GetFileName(layer.path));
}
doc.WriteToFile(Path.Combine(m_Path, "Contents.json"));
}
}
class AssetBrandAssetGroup : AssetCatalogItem
{
class AssetBrandAssetItem
{
internal string idiom = null;
internal string role = null;
internal int width, height;
internal AssetCatalogItem item = null;
}
List<AssetBrandAssetItem> m_Items = new List<AssetBrandAssetItem>();
internal AssetBrandAssetGroup(string assetCatalogPath, string name, string authorId) : base(name, authorId)
{
m_Path = Path.Combine(assetCatalogPath, name + ".brandassets");
}
void AddItem(AssetCatalogItem item, string idiom, string role, int width, int height)
{
foreach (var it in m_Items)
{
if (it.item.name == item.name)
throw new Exception("An item with given name already exists");
}
var newItem = new AssetBrandAssetItem();
newItem.item = item;
newItem.idiom = idiom;
newItem.role = role;
newItem.width = width;
newItem.height = height;
m_Items.Add(newItem);
}
public AssetImageSet OpenImageSet(string name, string idiom, string role, int width, int height)
{
var newItem = new AssetImageSet(m_Path, name, authorId);
AddItem(newItem, idiom, role, width, height);
return newItem;
}
public AssetImageStack OpenImageStack(string name, string idiom, string role, int width, int height)
{
var newItem = new AssetImageStack(m_Path, name, authorId);
AddItem(newItem, idiom, role, width, height);
return newItem;
}
public override void Write(List<string> warnings)
{
Directory.CreateDirectory(m_Path);
var doc = new JsonDocument();
WriteInfoToJson(doc);
var docAssets = doc.root.CreateArray("assets");
foreach (var item in m_Items)
{
var docAsset = docAssets.AddDict();
docAsset.SetString("size", String.Format("{0}x{1}", item.width, item.height));
docAsset.SetString("idiom", item.idiom);
docAsset.SetString("role", item.role);
docAsset.SetString("filename", Path.GetFileName(item.item.path));
item.item.Write(warnings);
}
doc.WriteToFile(Path.Combine(m_Path, "Contents.json"));
}
}
} // namespace UnityEditor.iOS.Xcode
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 46dd33873affe4e5caf86cb784bd831a
timeCreated: 1496741691
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+257
View File
@@ -0,0 +1,257 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Linq;
namespace ChillyRoom.UnityEditor.iOS.Xcode
{
internal class JsonElement
{
protected JsonElement() {}
// convenience methods
public string AsString() { return ((JsonElementString)this).value; }
public int AsInteger() { return ((JsonElementInteger)this).value; }
public bool AsBoolean() { return ((JsonElementBoolean)this).value; }
public JsonElementArray AsArray() { return (JsonElementArray)this; }
public JsonElementDict AsDict() { return (JsonElementDict)this; }
public JsonElement this[string key]
{
get { return AsDict()[key]; }
set { AsDict()[key] = value; }
}
}
internal class JsonElementString : JsonElement
{
public JsonElementString(string v) { value = v; }
public string value;
}
internal class JsonElementInteger : JsonElement
{
public JsonElementInteger(int v) { value = v; }
public int value;
}
internal class JsonElementBoolean : JsonElement
{
public JsonElementBoolean(bool v) { value = v; }
public bool value;
}
internal class JsonElementDict : JsonElement
{
public JsonElementDict() : base() {}
private SortedDictionary<string, JsonElement> m_PrivateValue = new SortedDictionary<string, JsonElement>();
public IDictionary<string, JsonElement> values { get { return m_PrivateValue; }}
new public JsonElement this[string key]
{
get {
if (values.ContainsKey(key))
return values[key];
return null;
}
set { this.values[key] = value; }
}
public bool Contains(string key)
{
return values.ContainsKey(key);
}
public void Remove(string key)
{
values.Remove(key);
}
// convenience methods
public void SetInteger(string key, int val)
{
values[key] = new JsonElementInteger(val);
}
public void SetString(string key, string val)
{
values[key] = new JsonElementString(val);
}
public void SetBoolean(string key, bool val)
{
values[key] = new JsonElementBoolean(val);
}
public JsonElementArray CreateArray(string key)
{
var v = new JsonElementArray();
values[key] = v;
return v;
}
public JsonElementDict CreateDict(string key)
{
var v = new JsonElementDict();
values[key] = v;
return v;
}
}
internal class JsonElementArray : JsonElement
{
public JsonElementArray() : base() {}
public List<JsonElement> values = new List<JsonElement>();
// convenience methods
public void AddString(string val)
{
values.Add(new JsonElementString(val));
}
public void AddInteger(int val)
{
values.Add(new JsonElementInteger(val));
}
public void AddBoolean(bool val)
{
values.Add(new JsonElementBoolean(val));
}
public JsonElementArray AddArray()
{
var v = new JsonElementArray();
values.Add(v);
return v;
}
public JsonElementDict AddDict()
{
var v = new JsonElementDict();
values.Add(v);
return v;
}
}
internal class JsonDocument
{
public JsonElementDict root;
public string indentString = " ";
public JsonDocument()
{
root = new JsonElementDict();
}
void AppendIndent(StringBuilder sb, int indent)
{
for (int i = 0; i < indent; ++i)
sb.Append(indentString);
}
void WriteString(StringBuilder sb, string str)
{
// TODO: escape
sb.Append('"');
sb.Append(str);
sb.Append('"');
}
void WriteBoolean(StringBuilder sb, bool value)
{
sb.Append(value ? "true" : "false");
}
void WriteInteger(StringBuilder sb, int value)
{
sb.Append(value.ToString());
}
void WriteDictKeyValue(StringBuilder sb, string key, JsonElement value, int indent)
{
sb.Append("\n");
AppendIndent(sb, indent);
WriteString(sb, key);
sb.Append(" : ");
if (value is JsonElementString)
WriteString(sb, value.AsString());
else if (value is JsonElementInteger)
WriteInteger(sb, value.AsInteger());
else if (value is JsonElementBoolean)
WriteBoolean(sb, value.AsBoolean());
else if (value is JsonElementDict)
WriteDict(sb, value.AsDict(), indent);
else if (value is JsonElementArray)
WriteArray(sb, value.AsArray(), indent);
}
void WriteDict(StringBuilder sb, JsonElementDict el, int indent)
{
sb.Append("{");
bool hasElement = false;
foreach (var key in el.values.Keys)
{
if (hasElement)
sb.Append(","); // trailing commas not supported
WriteDictKeyValue(sb, key, el[key], indent+1);
hasElement = true;
}
sb.Append("\n");
AppendIndent(sb, indent);
sb.Append("}");
}
void WriteArray(StringBuilder sb, JsonElementArray el, int indent)
{
sb.Append("[");
bool hasElement = false;
foreach (var value in el.values)
{
if (hasElement)
sb.Append(","); // trailing commas not supported
sb.Append("\n");
AppendIndent(sb, indent+1);
if (value is JsonElementString)
WriteString(sb, value.AsString());
else if (value is JsonElementInteger)
WriteInteger(sb, value.AsInteger());
else if (value is JsonElementBoolean)
WriteBoolean(sb, value.AsBoolean());
else if (value is JsonElementDict)
WriteDict(sb, value.AsDict(), indent+1);
else if (value is JsonElementArray)
WriteArray(sb, value.AsArray(), indent+1);
hasElement = true;
}
sb.Append("\n");
AppendIndent(sb, indent);
sb.Append("]");
}
public void WriteToFile(string path)
{
File.WriteAllText(path, WriteToString());
}
public void WriteToStream(TextWriter tw)
{
tw.Write(WriteToString());
}
public string WriteToString()
{
var sb = new StringBuilder();
WriteDict(sb, root, 0);
return sb.ToString();
}
}
} // namespace UnityEditor.iOS.Xcode
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 052ac8a8c9ae3466f94f7b3b6c5b61af
timeCreated: 1496741691
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+9
View File
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 7625017be5ff149a6b0f20ee645ce11e
folderAsset: yes
timeCreated: 1496741689
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+106
View File
@@ -0,0 +1,106 @@
using System.Collections.Generic;
using System.Collections;
using System;
namespace ChillyRoom.UnityEditor.iOS.Xcode.PBX
{
class PBXElement
{
protected PBXElement() {}
// convenience methods
public string AsString() { return ((PBXElementString)this).value; }
public PBXElementArray AsArray() { return (PBXElementArray)this; }
public PBXElementDict AsDict() { return (PBXElementDict)this; }
public PBXElement this[string key]
{
get { return AsDict()[key]; }
set { AsDict()[key] = value; }
}
}
class PBXElementString : PBXElement
{
public PBXElementString(string v) { value = v; }
public string value;
}
class PBXElementDict : PBXElement
{
public PBXElementDict() : base() {}
private Dictionary<string, PBXElement> m_PrivateValue = new Dictionary<string, PBXElement>();
public IDictionary<string, PBXElement> values { get { return m_PrivateValue; }}
new public PBXElement this[string key]
{
get {
if (values.ContainsKey(key))
return values[key];
return null;
}
set { this.values[key] = value; }
}
public bool Contains(string key)
{
return values.ContainsKey(key);
}
public void Remove(string key)
{
values.Remove(key);
}
public void SetString(string key, string val)
{
values[key] = new PBXElementString(val);
}
public PBXElementArray CreateArray(string key)
{
var v = new PBXElementArray();
values[key] = v;
return v;
}
public PBXElementDict CreateDict(string key)
{
var v = new PBXElementDict();
values[key] = v;
return v;
}
}
class PBXElementArray : PBXElement
{
public PBXElementArray() : base() {}
public List<PBXElement> values = new List<PBXElement>();
// convenience methods
public void AddString(string val)
{
values.Add(new PBXElementString(val));
}
public PBXElementArray AddArray()
{
var v = new PBXElementArray();
values.Add(v);
return v;
}
public PBXElementDict AddDict()
{
var v = new PBXElementDict();
values.Add(v);
return v;
}
}
} // namespace UnityEditor.iOS.Xcode
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 83cffec4be0e045258109e9714cdaa5f
timeCreated: 1496741691
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+243
View File
@@ -0,0 +1,243 @@
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.IO;
using System.Linq;
using System;
namespace ChillyRoom.UnityEditor.iOS.Xcode.PBX
{
enum TokenType
{
EOF,
Invalid,
String,
QuotedString,
Comment,
Semicolon, // ;
Comma, // ,
Eq, // =
LParen, // (
RParen, // )
LBrace, // {
RBrace, // }
}
class Token
{
public TokenType type;
// the line of the input stream the token starts in (0-based)
public int line;
// start and past-the-end positions of the token in the input stream
public int begin, end;
}
class TokenList : List<Token>
{
}
class Lexer
{
string text;
int pos;
int length;
int line;
public static TokenList Tokenize(string text)
{
var lexer = new Lexer();
lexer.SetText(text);
return lexer.ScanAll();
}
public void SetText(string text)
{
this.text = text + " "; // to prevent out-of-bounds access during look ahead
pos = 0;
length = text.Length;
line = 0;
}
public TokenList ScanAll()
{
var tokens = new TokenList();
while (true)
{
var tok = new Token();
ScanOne(tok);
tokens.Add(tok);
if (tok.type == TokenType.EOF)
break;
}
return tokens;
}
void UpdateNewlineStats(char ch)
{
if (ch == '\n')
line++;
}
// tokens list is modified in the case when we add BrokenLine token and need to remove already
// added tokens for the current line
void ScanOne(Token tok)
{
while (true)
{
while (pos < length && Char.IsWhiteSpace(text[pos]))
{
UpdateNewlineStats(text[pos]);
pos++;
}
if (pos >= length)
{
tok.type = TokenType.EOF;
break;
}
char ch = text[pos];
char ch2 = text[pos+1];
if (ch == '\"')
ScanQuotedString(tok);
else if (ch == '/' && ch2 == '*')
ScanMultilineComment(tok);
else if (ch == '/' && ch2 == '/')
ScanComment(tok);
else if (IsOperator(ch))
ScanOperator(tok);
else
ScanString(tok); // be more robust and accept whatever is left
return;
}
}
void ScanString(Token tok)
{
tok.type = TokenType.String;
tok.begin = pos;
while (pos < length)
{
char ch = text[pos];
char ch2 = text[pos+1];
if (Char.IsWhiteSpace(ch))
break;
else if (ch == '\"')
break;
else if (ch == '/' && ch2 == '*')
break;
else if (ch == '/' && ch2 == '/')
break;
else if (IsOperator(ch))
break;
pos++;
}
tok.end = pos;
tok.line = line;
}
void ScanQuotedString(Token tok)
{
tok.type = TokenType.QuotedString;
tok.begin = pos;
pos++;
while (pos < length)
{
// ignore escaped quotes
if (text[pos] == '\\' && text[pos+1] == '\"')
{
pos += 2;
continue;
}
// note that we close unclosed quotes
if (text[pos] == '\"')
break;
UpdateNewlineStats(text[pos]);
pos++;
}
pos++;
tok.end = pos;
tok.line = line;
}
void ScanMultilineComment(Token tok)
{
tok.type = TokenType.Comment;
tok.begin = pos;
pos += 2;
while (pos < length)
{
if (text[pos] == '*' && text[pos+1] == '/')
break;
// we support multiline comments
UpdateNewlineStats(text[pos]);
pos++;
}
pos += 2;
tok.end = pos;
tok.line = line;
}
void ScanComment(Token tok)
{
tok.type = TokenType.Comment;
tok.begin = pos;
pos += 2;
while (pos < length)
{
if (text[pos] == '\n')
break;
pos++;
}
UpdateNewlineStats(text[pos]);
pos++;
tok.end = pos;
tok.line = line;
}
bool IsOperator(char ch)
{
if (ch == ';' || ch == ',' || ch == '=' || ch == '(' || ch == ')' || ch == '{' || ch == '}')
return true;
return false;
}
void ScanOperator(Token tok)
{
switch (text[pos])
{
case ';': ScanOperatorSpecific(tok, TokenType.Semicolon); return;
case ',': ScanOperatorSpecific(tok, TokenType.Comma); return;
case '=': ScanOperatorSpecific(tok, TokenType.Eq); return;
case '(': ScanOperatorSpecific(tok, TokenType.LParen); return;
case ')': ScanOperatorSpecific(tok, TokenType.RParen); return;
case '{': ScanOperatorSpecific(tok, TokenType.LBrace); return;
case '}': ScanOperatorSpecific(tok, TokenType.RBrace); return;
default: return;
}
}
void ScanOperatorSpecific(Token tok, TokenType type)
{
tok.type = type;
tok.begin = pos;
pos++;
tok.end = pos;
tok.line = line;
}
}
} // namespace UnityEditor.iOS.Xcode
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 9766f6c4eb5ef42f99c0d5f86e34ba84
timeCreated: 1496741691
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
File diff suppressed because it is too large. Load diff
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 67cf10cf994604c719f706525399f867
timeCreated: 1496741691
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+171
View File
@@ -0,0 +1,171 @@
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.IO;
using System.Linq;
using System;
namespace ChillyRoom.UnityEditor.iOS.Xcode.PBX
{
class ValueAST {}
// IdentifierAST := <quoted string> \ <string>
class IdentifierAST : ValueAST
{
public int value = 0; // token id
}
// TreeAST := '{' KeyValuePairList '}'
// KeyValuePairList := KeyValuePair ',' KeyValuePairList
// KeyValuePair ','
// (empty)
class TreeAST : ValueAST
{
public List<KeyValueAST> values = new List<KeyValueAST>();
}
// ListAST := '(' ValueList ')'
// ValueList := ValueAST ',' ValueList
// ValueAST ','
// (empty)
class ArrayAST : ValueAST
{
public List<ValueAST> values = new List<ValueAST>();
}
// KeyValueAST := IdentifierAST '=' ValueAST ';'
// ValueAST := IdentifierAST | TreeAST | ListAST
class KeyValueAST
{
public IdentifierAST key = null;
public ValueAST value = null; // either IdentifierAST, TreeAST or ListAST
}
class Parser
{
TokenList tokens;
int currPos;
public Parser(TokenList tokens)
{
this.tokens = tokens;
currPos = SkipComments(0);
}
int SkipComments(int pos)
{
while (pos < tokens.Count && tokens[pos].type == TokenType.Comment)
{
pos++;
}
return pos;
}
// returns new position
int IncInternal(int pos)
{
if (pos >= tokens.Count)
return pos;
pos++;
return SkipComments(pos);
}
// Increments current pointer if not past the end, returns previous pos
int Inc()
{
int prev = currPos;
currPos = IncInternal(currPos);
return prev;
}
// Returns the token type of the current token
TokenType Tok()
{
if (currPos >= tokens.Count)
return TokenType.EOF;
return tokens[currPos].type;
}
void SkipIf(TokenType type)
{
if (Tok() == type)
Inc();
}
string GetErrorMsg()
{
return "Invalid PBX project (parsing line " + tokens[currPos].line + ")";
}
public IdentifierAST ParseIdentifier()
{
if (Tok() != TokenType.String && Tok() != TokenType.QuotedString)
throw new Exception(GetErrorMsg());
var ast = new IdentifierAST();
ast.value = Inc();
return ast;
}
public TreeAST ParseTree()
{
if (Tok() != TokenType.LBrace)
throw new Exception(GetErrorMsg());
Inc();
var ast = new TreeAST();
while (Tok() != TokenType.RBrace && Tok() != TokenType.EOF)
{
ast.values.Add(ParseKeyValue());
}
SkipIf(TokenType.RBrace);
return ast;
}
public ArrayAST ParseList()
{
if (Tok() != TokenType.LParen)
throw new Exception(GetErrorMsg());
Inc();
var ast = new ArrayAST();
while (Tok() != TokenType.RParen && Tok() != TokenType.EOF)
{
ast.values.Add(ParseValue());
SkipIf(TokenType.Comma);
}
SkipIf(TokenType.RParen);
return ast;
}
// throws on error
public KeyValueAST ParseKeyValue()
{
var ast = new KeyValueAST();
ast.key = ParseIdentifier();
if (Tok() != TokenType.Eq)
throw new Exception(GetErrorMsg());
Inc(); // skip '='
ast.value = ParseValue();
SkipIf(TokenType.Semicolon);
return ast;
}
// throws on error
public ValueAST ParseValue()
{
if (Tok() == TokenType.String || Tok() == TokenType.QuotedString)
return ParseIdentifier();
else if (Tok() == TokenType.LBrace)
return ParseTree();
else if (Tok() == TokenType.LParen)
return ParseList();
throw new Exception(GetErrorMsg());
}
}
} // namespace UnityEditor.iOS.Xcode
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 5ce5a244bc4e04a668ab097db4456665
timeCreated: 1496741691
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+122
View File
@@ -0,0 +1,122 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
// Basr classes for section handling
namespace ChillyRoom.UnityEditor.iOS.Xcode.PBX
{
// common base
internal abstract class SectionBase
{
public abstract void AddObject(string key, PBXElementDict value);
public abstract void WriteSection(StringBuilder sb, GUIDToCommentMap comments);
}
// known section: contains objects that we care about
internal class KnownSectionBase<T> : SectionBase where T : PBXObjectData, new()
{
private Dictionary<string, T> m_Entries = new Dictionary<string, T>();
private string m_Name;
public KnownSectionBase(string sectionName)
{
m_Name = sectionName;
}
public IEnumerable<KeyValuePair<string, T>> GetEntries()
{
return m_Entries;
}
public IEnumerable<string> GetGuids()
{
return m_Entries.Keys;
}
public IEnumerable<T> GetObjects()
{
return m_Entries.Values;
}
public override void AddObject(string key, PBXElementDict value)
{
T obj = new T();
obj.guid = key;
obj.SetPropertiesWhenSerializing(value);
obj.UpdateVars();
m_Entries[obj.guid] = obj;
}
public override void WriteSection(StringBuilder sb, GUIDToCommentMap comments)
{
if (m_Entries.Count == 0)
return; // do not write empty sections
sb.AppendFormat("\n\n/* Begin {0} section */", m_Name);
var keys = new List<string>(m_Entries.Keys);
keys.Sort(StringComparer.Ordinal);
foreach (string key in keys)
{
T obj = m_Entries[key];
obj.UpdateProps();
sb.Append("\n\t\t");
comments.WriteStringBuilder(sb, obj.guid);
sb.Append(" = ");
Serializer.WriteDict(sb, obj.GetPropertiesWhenSerializing(), 2,
obj.shouldCompact, obj.checker, comments);
sb.Append(";");
}
sb.AppendFormat("\n/* End {0} section */", m_Name);
}
// returns null if not found
public T this[string guid]
{
get {
if (m_Entries.ContainsKey(guid))
return m_Entries[guid];
return null;
}
}
public bool HasEntry(string guid)
{
return m_Entries.ContainsKey(guid);
}
public void AddEntry(T obj)
{
m_Entries[obj.guid] = obj;
}
public void RemoveEntry(string guid)
{
if (m_Entries.ContainsKey(guid))
m_Entries.Remove(guid);
}
}
// we assume there is only one PBXProject entry
internal class PBXProjectSection : KnownSectionBase<PBXProjectObjectData>
{
public PBXProjectSection() : base("PBXProject")
{
}
public PBXProjectObjectData project
{
get {
foreach (var kv in GetEntries())
return kv.Value;
return null;
}
}
}
} // UnityEditor.iOS.Xcode
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 60639b138b83f4ce9b2448c38a6ba285
timeCreated: 1496741691
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+259
View File
@@ -0,0 +1,259 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Linq;
namespace ChillyRoom.UnityEditor.iOS.Xcode.PBX
{
class PropertyCommentChecker
{
private int m_Level;
private bool m_All;
private List<List<string>> m_Props;
/* The argument is an array of matcher strings each of which determine
whether a property with a certain path needs to be decorated with a
comment.
A path is a number of path elements concatenated by '/'. The last path
element is either:
the key if we're referring to a dict key
the value if we're referring to a value in an array
the value if we're referring to a value in a dict
All other path elements are either:
the key if the container is dict
'*' if the container is array
Path matcher has the same structure as a path, except that any of the
elements may be '*'. Matcher matches a path if both have the same number
of elements and for each pair matcher element is the same as path element
or is '*'.
a/b/c matches a/b/c but not a/b nor a/b/c/d
a/* /c matches a/d/c but not a/b nor a/b/c/d
* /* /* matches any path from three elements
*/
protected PropertyCommentChecker(int level, List<List<string>> props)
{
m_Level = level;
m_All = false;
m_Props = props;
}
public PropertyCommentChecker()
{
m_Level = 0;
m_All = false;
m_Props = new List<List<string>>();
}
public PropertyCommentChecker(IEnumerable<string> props)
{
m_Level = 0;
m_All = false;
m_Props = new List<List<string>>();
foreach (var prop in props)
{
m_Props.Add(new List<string>(prop.Split('/')));
}
}
bool CheckContained(string prop)
{
if (m_All)
return true;
foreach (var list in m_Props)
{
if (list.Count == m_Level+1)
{
if (list[m_Level] == prop)
return true;
if (list[m_Level] == "*")
{
m_All = true; // short-circuit all at this level
return true;
}
}
}
return false;
}
public bool CheckStringValueInArray(string value) { return CheckContained(value); }
public bool CheckKeyInDict(string key) { return CheckContained(key); }
public bool CheckStringValueInDict(string key, string value)
{
foreach (var list in m_Props)
{
if (list.Count == m_Level + 2)
{
if ((list[m_Level] == "*" || list[m_Level] == key) &&
list[m_Level+1] == "*" || list[m_Level+1] == value)
return true;
}
}
return false;
}
public PropertyCommentChecker NextLevel(string prop)
{
var newList = new List<List<string>>();
foreach (var list in m_Props)
{
if (list.Count <= m_Level+1)
continue;
if (list[m_Level] == "*" || list[m_Level] == prop)
newList.Add(list);
}
return new PropertyCommentChecker(m_Level + 1, newList);
}
}
class Serializer
{
public static PBXElementDict ParseTreeAST(TreeAST ast, TokenList tokens, string text)
{
var el = new PBXElementDict();
foreach (var kv in ast.values)
{
PBXElementString key = ParseIdentifierAST(kv.key, tokens, text);
PBXElement value = ParseValueAST(kv.value, tokens, text);
el[key.value] = value;
}
return el;
}
public static PBXElementArray ParseArrayAST(ArrayAST ast, TokenList tokens, string text)
{
var el = new PBXElementArray();
foreach (var v in ast.values)
{
el.values.Add(ParseValueAST(v, tokens, text));
}
return el;
}
public static PBXElement ParseValueAST(ValueAST ast, TokenList tokens, string text)
{
if (ast is TreeAST)
return ParseTreeAST((TreeAST)ast, tokens, text);
if (ast is ArrayAST)
return ParseArrayAST((ArrayAST)ast, tokens, text);
if (ast is IdentifierAST)
return ParseIdentifierAST((IdentifierAST)ast, tokens, text);
return null;
}
public static PBXElementString ParseIdentifierAST(IdentifierAST ast, TokenList tokens, string text)
{
Token tok = tokens[ast.value];
string value;
switch (tok.type)
{
case TokenType.String:
value = text.Substring(tok.begin, tok.end - tok.begin);
return new PBXElementString(value);
case TokenType.QuotedString:
value = text.Substring(tok.begin, tok.end - tok.begin);
value = PBXStream.UnquoteString(value);
return new PBXElementString(value);
default:
throw new Exception("Internal parser error");
}
}
static string k_Indent = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
static string GetIndent(int indent)
{
return k_Indent.Substring(0, indent);
}
static void WriteStringImpl(StringBuilder sb, string s, bool comment, GUIDToCommentMap comments)
{
if (comment)
comments.WriteStringBuilder(sb, s);
else
sb.Append(PBXStream.QuoteStringIfNeeded(s));
}
public static void WriteDictKeyValue(StringBuilder sb, string key, PBXElement value, int indent, bool compact,
PropertyCommentChecker checker, GUIDToCommentMap comments)
{
if (!compact)
{
sb.Append("\n");
sb.Append(GetIndent(indent));
}
WriteStringImpl(sb, key, checker.CheckKeyInDict(key), comments);
sb.Append(" = ");
if (value is PBXElementString)
WriteStringImpl(sb, value.AsString(), checker.CheckStringValueInDict(key, value.AsString()), comments);
else if (value is PBXElementDict)
WriteDict(sb, value.AsDict(), indent, compact, checker.NextLevel(key), comments);
else if (value is PBXElementArray)
WriteArray(sb, value.AsArray(), indent, compact, checker.NextLevel(key), comments);
sb.Append(";");
if (compact)
sb.Append(" ");
}
public static void WriteDict(StringBuilder sb, PBXElementDict el, int indent, bool compact,
PropertyCommentChecker checker, GUIDToCommentMap comments)
{
sb.Append("{");
if (el.Contains("isa"))
WriteDictKeyValue(sb, "isa", el["isa"], indent+1, compact, checker, comments);
var keys = new List<string>(el.values.Keys);
keys.Sort(StringComparer.Ordinal);
foreach (var key in keys)
{
if (key != "isa")
WriteDictKeyValue(sb, key, el[key], indent+1, compact, checker, comments);
}
if (!compact)
{
sb.Append("\n");
sb.Append(GetIndent(indent));
}
sb.Append("}");
}
public static void WriteArray(StringBuilder sb, PBXElementArray el, int indent, bool compact,
PropertyCommentChecker checker, GUIDToCommentMap comments)
{
sb.Append("(");
foreach (var value in el.values)
{
if (!compact)
{
sb.Append("\n");
sb.Append(GetIndent(indent+1));
}
if (value is PBXElementString)
WriteStringImpl(sb, value.AsString(), checker.CheckStringValueInArray(value.AsString()), comments);
else if (value is PBXElementDict)
WriteDict(sb, value.AsDict(), indent+1, compact, checker.NextLevel("*"), comments);
else if (value is PBXElementArray)
WriteArray(sb, value.AsArray(), indent+1, compact, checker.NextLevel("*"), comments);
sb.Append(",");
if (compact)
sb.Append(" ");
}
if (!compact)
{
sb.Append("\n");
sb.Append(GetIndent(indent));
}
sb.Append(")");
}
}
} // namespace UnityEditor.iOS.Xcode
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: afe8316bf614347729fac3466d7c77f2
timeCreated: 1496741691
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+300
View File
@@ -0,0 +1,300 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
namespace ChillyRoom.UnityEditor.iOS.Xcode.PBX
{
internal class GUIDToCommentMap
{
private Dictionary<string, string> m_Dict = new Dictionary<string, string>();
public string this[string guid]
{
get {
if (m_Dict.ContainsKey(guid))
return m_Dict[guid];
return null;
}
}
public void Add(string guid, string comment)
{
if (m_Dict.ContainsKey(guid))
return;
m_Dict.Add(guid, comment);
}
public void Remove(string guid)
{
m_Dict.Remove(guid);
}
public string Write(string guid)
{
string comment = this[guid];
if (comment == null)
return guid;
return String.Format("{0} /* {1} */", guid, comment);
}
public void WriteStringBuilder(StringBuilder sb, string guid)
{
string comment = this[guid];
if (comment == null)
sb.Append(guid);
else
{
// {0} /* {1} */
sb.Append(guid).Append(" /* ").Append(comment).Append(" */");
}
}
}
internal class PBXGUID
{
internal delegate string GuidGenerator();
// We allow changing Guid generator to make testing of PBXProject possible
private static GuidGenerator guidGenerator = DefaultGuidGenerator;
internal static string DefaultGuidGenerator()
{
return Guid.NewGuid().ToString("N").Substring(8).ToUpper();
}
internal static void SetGuidGenerator(GuidGenerator generator)
{
guidGenerator = generator;
}
// Generates a GUID.
public static string Generate()
{
return guidGenerator();
}
}
internal class PBXRegex
{
public static string GuidRegexString = "[A-Fa-f0-9]{24}";
}
internal class PBXStream
{
static bool DontNeedQuotes(string src)
{
// using a regex instead of explicit matching slows down common cases by 40%
if (src.Length == 0)
return false;
bool hasSlash = false;
for (int i = 0; i < src.Length; ++i)
{
char c = src[i];
if (Char.IsLetterOrDigit(c) || c == '.' || c == '*' || c == '_')
continue;
if (c == '/')
{
hasSlash = true;
continue;
}
return false;
}
if (hasSlash)
{
if (src.Contains("//") || src.Contains("/*") || src.Contains("*/"))
return false;
}
return true;
}
// Quotes the given string if it contains special characters. Note: if the string already
// contains quotes, then they are escaped and the entire string quoted again
public static string QuoteStringIfNeeded(string src)
{
if (DontNeedQuotes(src))
return src;
return "\"" + src.Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\n", "\\n") + "\"";
}
// If the given string is quoted, removes the quotes and unescapes any quotes within the string
public static string UnquoteString(string src)
{
if (!src.StartsWith("\"") || !src.EndsWith("\""))
return src;
return src.Substring(1, src.Length - 2).Replace("\\\\", "\u569f").Replace("\\\"", "\"")
.Replace("\\n", "\n").Replace("\u569f", "\\"); // U+569f is a rarely used Chinese character
}
}
internal enum PBXFileType
{
NotBuildable,
Framework,
Source,
Resource,
CopyFile
}
internal class FileTypeUtils
{
internal class FileTypeDesc
{
public FileTypeDesc(string typeName, PBXFileType type)
{
this.name = typeName;
this.type = type;
this.isExplicit = false;
}
public FileTypeDesc(string typeName, PBXFileType type, bool isExplicit)
{
this.name = typeName;
this.type = type;
this.isExplicit = isExplicit;
}
public string name;
public PBXFileType type;
public bool isExplicit;
}
private static readonly Dictionary<string, FileTypeDesc> types =
new Dictionary<string, FileTypeDesc>
{
{ "a", new FileTypeDesc("archive.ar", PBXFileType.Framework) },
{ "app", new FileTypeDesc("wrapper.application", PBXFileType.NotBuildable, true) },
{ "appex", new FileTypeDesc("wrapper.app-extension", PBXFileType.CopyFile) },
{ "bin", new FileTypeDesc("archive.macbinary", PBXFileType.Resource) },
{ "s", new FileTypeDesc("sourcecode.asm", PBXFileType.Source) },
{ "c", new FileTypeDesc("sourcecode.c.c", PBXFileType.Source) },
{ "cc", new FileTypeDesc("sourcecode.cpp.cpp", PBXFileType.Source) },
{ "cpp", new FileTypeDesc("sourcecode.cpp.cpp", PBXFileType.Source) },
{ "swift", new FileTypeDesc("sourcecode.swift", PBXFileType.Source) },
{ "dll", new FileTypeDesc("file", PBXFileType.NotBuildable) },
{ "framework", new FileTypeDesc("wrapper.framework", PBXFileType.Framework) },
{ "h", new FileTypeDesc("sourcecode.c.h", PBXFileType.NotBuildable) },
{ "pch", new FileTypeDesc("sourcecode.c.h", PBXFileType.NotBuildable) },
{ "icns", new FileTypeDesc("image.icns", PBXFileType.Resource) },
{ "xcassets", new FileTypeDesc("folder.assetcatalog", PBXFileType.Resource) },
{ "inc", new FileTypeDesc("sourcecode.inc", PBXFileType.NotBuildable) },
{ "m", new FileTypeDesc("sourcecode.c.objc", PBXFileType.Source) },
{ "mm", new FileTypeDesc("sourcecode.cpp.objcpp", PBXFileType.Source ) },
{ "nib", new FileTypeDesc("wrapper.nib", PBXFileType.Resource) },
{ "plist", new FileTypeDesc("text.plist.xml", PBXFileType.Resource) },
{ "png", new FileTypeDesc("image.png", PBXFileType.Resource) },
{ "rtf", new FileTypeDesc("text.rtf", PBXFileType.Resource) },
{ "tiff", new FileTypeDesc("image.tiff", PBXFileType.Resource) },
{ "txt", new FileTypeDesc("text", PBXFileType.Resource) },
{ "json", new FileTypeDesc("text.json", PBXFileType.Resource) },
{ "xcodeproj", new FileTypeDesc("wrapper.pb-project", PBXFileType.NotBuildable) },
{ "xib", new FileTypeDesc("file.xib", PBXFileType.Resource) },
{ "strings", new FileTypeDesc("text.plist.strings", PBXFileType.Resource) },
{ "storyboard",new FileTypeDesc("file.storyboard", PBXFileType.Resource) },
{ "bundle", new FileTypeDesc("wrapper.plug-in", PBXFileType.Resource) },
{ "dylib", new FileTypeDesc("compiled.mach-o.dylib", PBXFileType.Framework) },
{ "tbd", new FileTypeDesc("sourcecode.text-based-dylib-definition", PBXFileType.Framework) }
};
public static string TrimExtension(string ext)
{
return ext.TrimStart('.');
}
public static bool IsKnownExtension(string ext)
{
ext = TrimExtension(ext);
return types.ContainsKey(ext);
}
internal static bool IsFileTypeExplicit(string ext)
{
ext = TrimExtension(ext);
if (types.ContainsKey(ext))
return types[ext].isExplicit;
return false;
}
public static PBXFileType GetFileType(string ext, bool isFolderRef)
{
ext = TrimExtension(ext);
if (isFolderRef)
return PBXFileType.Resource;
if (!types.ContainsKey(ext))
return PBXFileType.Resource;
return types[ext].type;
}
public static string GetTypeName(string ext)
{
ext = TrimExtension(ext);
if (types.ContainsKey(ext))
return types[ext].name;
// Xcode actually checks the file contents to determine the file type.
// Text files have "text" type and all other files have "file" type.
// Since we can't reasonably determine whether the file in question is
// a text file, we just take the safe route and return "file" type.
return "file";
}
public static bool IsBuildableFile(string ext)
{
ext = TrimExtension(ext);
if (!types.ContainsKey(ext))
return true;
if (types[ext].type != PBXFileType.NotBuildable)
return true;
return false;
}
public static bool IsBuildable(string ext, bool isFolderReference)
{
ext = TrimExtension(ext);
if (isFolderReference)
return true;
return IsBuildableFile(ext);
}
private static readonly Dictionary<PBXSourceTree, string> sourceTree = new Dictionary<PBXSourceTree, string>
{
{ PBXSourceTree.Absolute, "<absolute>" },
{ PBXSourceTree.Group, "<group>" },
{ PBXSourceTree.Build, "BUILT_PRODUCTS_DIR" },
{ PBXSourceTree.Developer, "DEVELOPER_DIR" },
{ PBXSourceTree.Sdk, "SDKROOT" },
{ PBXSourceTree.Source, "SOURCE_ROOT" },
};
private static readonly Dictionary<string, PBXSourceTree> stringToSourceTreeMap = new Dictionary<string, PBXSourceTree>
{
{ "<absolute>", PBXSourceTree.Absolute },
{ "<group>", PBXSourceTree.Group },
{ "BUILT_PRODUCTS_DIR", PBXSourceTree.Build },
{ "DEVELOPER_DIR", PBXSourceTree.Developer },
{ "SDKROOT", PBXSourceTree.Sdk },
{ "SOURCE_ROOT", PBXSourceTree.Source },
};
internal static string SourceTreeDesc(PBXSourceTree tree)
{
return sourceTree[tree];
}
// returns PBXSourceTree.Source on error
internal static PBXSourceTree ParseSourceTree(string tree)
{
if (stringToSourceTreeMap.ContainsKey(tree))
return stringToSourceTreeMap[tree];
return PBXSourceTree.Source;
}
internal static List<PBXSourceTree> AllAbsoluteSourceTrees()
{
return new List<PBXSourceTree>{PBXSourceTree.Absolute, PBXSourceTree.Build,
PBXSourceTree.Developer, PBXSourceTree.Sdk, PBXSourceTree.Source};
}
}
} // UnityEditor.iOS.Xcode
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 8eafbccf2ded14760af588ffcb1ca0f5
timeCreated: 1496741691
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+125
View File
@@ -0,0 +1,125 @@
namespace ChillyRoom.UnityEditor.iOS.Xcode
{
/// <summary>
/// List of all the capabilities available.
/// </summary>
public sealed class PBXCapabilityType
{
public static readonly PBXCapabilityType ApplePay = new PBXCapabilityType ("com.apple.ApplePay", true);
public static readonly PBXCapabilityType AppGroups = new PBXCapabilityType ("com.apple.ApplicationGroups.iOS", true);
public static readonly PBXCapabilityType AssociatedDomains = new PBXCapabilityType ("com.apple.SafariKeychain", true);
public static readonly PBXCapabilityType BackgroundModes = new PBXCapabilityType ("com.apple.BackgroundModes", false);
public static readonly PBXCapabilityType DataProtection = new PBXCapabilityType ("com.apple.DataProtection", true);
public static readonly PBXCapabilityType GameCenter = new PBXCapabilityType ("com.apple.GameCenter", false, "GameKit.framework");
public static readonly PBXCapabilityType HealthKit = new PBXCapabilityType ("com.apple.HealthKit", true, "HealthKit.framework");
public static readonly PBXCapabilityType HomeKit = new PBXCapabilityType ("com.apple.HomeKit", true, "HomeKit.framework");
public static readonly PBXCapabilityType iCloud = new PBXCapabilityType("com.apple.iCloud", true, "CloudKit.framework", true);
public static readonly PBXCapabilityType InAppPurchase = new PBXCapabilityType ("com.apple.InAppPurchase", false);
public static readonly PBXCapabilityType InterAppAudio = new PBXCapabilityType ("com.apple.InterAppAudio", true, "AudioToolbox.framework");
public static readonly PBXCapabilityType KeychainSharing = new PBXCapabilityType ("com.apple.KeychainSharing", true);
public static readonly PBXCapabilityType Maps = new PBXCapabilityType("com.apple.Maps.iOS", false, "MapKit.framework");
public static readonly PBXCapabilityType PersonalVPN = new PBXCapabilityType("com.apple.VPNLite", true, "NetworkExtension.framework");
public static readonly PBXCapabilityType PushNotifications = new PBXCapabilityType ("com.apple.Push", true);
public static readonly PBXCapabilityType Siri = new PBXCapabilityType ("com.apple.Siri", true);
public static readonly PBXCapabilityType Wallet = new PBXCapabilityType ("com.apple.Wallet", true, "PassKit.framework");
public static readonly PBXCapabilityType WirelessAccessoryConfiguration = new PBXCapabilityType("com.apple.WAC", true, "ExternalAccessory.framework");
private readonly string m_ID;
private readonly bool m_RequiresEntitlements;
private readonly string m_Framework;
private readonly bool m_OptionalFramework;
public bool optionalFramework
{
get { return m_OptionalFramework; }
}
public string framework
{
get { return m_Framework; }
}
public string id
{
get { return m_ID; }
}
public bool requiresEntitlements
{
get { return m_RequiresEntitlements; }
}
public struct TargetCapabilityPair
{
public string targetGuid;
public PBXCapabilityType capability;
public TargetCapabilityPair(string guid, PBXCapabilityType type)
{
targetGuid = guid;
capability = type;
}
}
/// <summary>
/// This private object represents what a capability changes in the PBXProject file
/// </summary>
/// <param name="id">The string used in the PBXProject file to identify the capability and mark it as enabled.</param>
/// <param name="requiresEntitlements">This capability requires an entitlements file therefore we need to add this entitlements file to the code signing entitlement.</param>
/// <param name="framework">Specify which framework need to be added to the project for this capability, if "" no framework are added.</param>
/// <param name="optionalFramework">Some capability (right now only iCloud) adds a framework, not all the time but just when some option are checked
/// this parameter indicates if one of them is checked.</param>
private PBXCapabilityType(string _id, bool _requiresEntitlements, string _framework = "", bool _optionalFramework = false)
{
m_ID = _id;
m_RequiresEntitlements = _requiresEntitlements;
m_Framework = _framework;
m_OptionalFramework = _optionalFramework;
}
public static PBXCapabilityType StringToPBXCapabilityType(string cap)
{
switch (cap)
{
case "com.apple.ApplePay":
return ApplePay;
case "com.apple.ApplicationGroups.iOS":
return AppGroups;
case "com.apple.SafariKeychain":
return AssociatedDomains;
case "com.apple.BackgroundModes":
return BackgroundModes;
case "com.apple.DataProtection":
return DataProtection;
case "com.apple.GameCenter":
return GameCenter;
case "com.apple.HealthKit":
return HealthKit;
case "com.apple.HomeKit":
return HomeKit;
case "com.apple.iCloud":
return iCloud;
case "com.apple.InAppPurchase":
return InAppPurchase;
case "com.apple.InterAppAudio":
return InterAppAudio;
case "com.apple.KeychainSharing":
return KeychainSharing;
case "com.apple.Maps.iOS":
return Maps;
case "com.apple.VPNLite":
return PersonalVPN;
case "com.apple.Push":
return PushNotifications;
case "com.apple.Siri":
return Siri;
case "com.apple.Wallet":
return Wallet;
case "WAC":
return WirelessAccessoryConfiguration;
default:
return null;
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 71f2dd6273cda4741b9b3bac41a9b765
timeCreated: 1496741691
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+106
View File
@@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
namespace ChillyRoom.UnityEditor.iOS.Xcode
{
internal class PBXPath
{
/// Replaces '\' with '/'. We need to apply this function to all paths that come from the user
/// of the API because we store paths to pbxproj and on windows we may get path with '\' slashes
/// instead of '/' slashes
public static string FixSlashes(string path)
{
if (path == null)
return null;
return path.Replace('\\', '/');
}
public static void Combine(string path1, PBXSourceTree tree1, string path2, PBXSourceTree tree2,
out string resPath, out PBXSourceTree resTree)
{
if (tree2 == PBXSourceTree.Group)
{
resPath = Combine(path1, path2);
resTree = tree1;
return;
}
resPath = path2;
resTree = tree2;
}
// Combines two paths
public static string Combine(string path1, string path2)
{
if (path2.StartsWith("/"))
return path2;
if (path1.EndsWith("/"))
return path1 + path2;
if (path1 == "")
return path2;
if (path2 == "")
return path1;
return path1 + "/" + path2;
}
public static string GetDirectory(string path)
{
path = path.TrimEnd('/');
int pos = path.LastIndexOf('/');
if (pos == -1)
return "";
else
return path.Substring(0, pos);
}
public static string GetCurrentDirectory()
{
if (Environment.OSVersion.Platform != PlatformID.MacOSX &&
Environment.OSVersion.Platform != PlatformID.Unix)
{
throw new Exception("PBX project compatible current directory can only obtained on OSX");
}
string path = Directory.GetCurrentDirectory();
path = FixSlashes(path);
if (!IsPathRooted(path))
return "/" + path;
return path;
}
public static string GetFilename(string path)
{
int pos = path.LastIndexOf('/');
if (pos == -1)
return path;
else
return path.Substring(pos + 1);
}
public static bool IsPathRooted(string path)
{
if (path == null || path.Length == 0)
return false;
return path[0] == '/';
}
public static string GetFullPath(string path)
{
if (IsPathRooted(path))
return path;
else
return Combine(GetCurrentDirectory(), path);
}
public static string[] Split(string path)
{
if (string.IsNullOrEmpty(path))
return new string[]{};
return path.Split(new[]{'/'}, StringSplitOptions.RemoveEmptyEntries);
}
}
} // UnityEditor.iOS.Xcode
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 57be5de7dcd844631b3e835186497c25
timeCreated: 1496741691
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
File diff suppressed because it is too large. Load diff
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 5923416dbf32e48428afbeee2b4eb48e
timeCreated: 1496741691
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+713
View File
@@ -0,0 +1,713 @@
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System;
using ChillyRoom.UnityEditor.iOS.Xcode.PBX;
namespace ChillyRoom.UnityEditor.iOS.Xcode
{
using PBXBuildFileSection = KnownSectionBase<PBXBuildFileData>;
using PBXFileReferenceSection = KnownSectionBase<PBXFileReferenceData>;
using PBXGroupSection = KnownSectionBase<PBXGroupData>;
using PBXContainerItemProxySection = KnownSectionBase<PBXContainerItemProxyData>;
using PBXReferenceProxySection = KnownSectionBase<PBXReferenceProxyData>;
using PBXSourcesBuildPhaseSection = KnownSectionBase<PBXSourcesBuildPhaseData>;
using PBXFrameworksBuildPhaseSection= KnownSectionBase<PBXFrameworksBuildPhaseData>;
using PBXResourcesBuildPhaseSection = KnownSectionBase<PBXResourcesBuildPhaseData>;
using PBXCopyFilesBuildPhaseSection = KnownSectionBase<PBXCopyFilesBuildPhaseData>;
using PBXShellScriptBuildPhaseSection = KnownSectionBase<PBXShellScriptBuildPhaseData>;
using PBXVariantGroupSection = KnownSectionBase<PBXVariantGroupData>;
using PBXNativeTargetSection = KnownSectionBase<PBXNativeTargetData>;
using PBXTargetDependencySection = KnownSectionBase<PBXTargetDependencyData>;
using XCBuildConfigurationSection = KnownSectionBase<XCBuildConfigurationData>;
using XCConfigurationListSection = KnownSectionBase<XCConfigurationListData>;
using UnknownSection = KnownSectionBase<PBXObjectData>;
internal class PBXProjectData
{
private Dictionary<string, SectionBase> m_Section = null;
private PBXElementDict m_RootElements = null;
private PBXElementDict m_UnknownObjects = null;
private string m_ObjectVersion = null;
private List<string> m_SectionOrder = null;
private Dictionary<string, UnknownSection> m_UnknownSections;
private PBXBuildFileSection buildFiles = null; // use BuildFiles* methods instead of manipulating directly
private PBXFileReferenceSection fileRefs = null; // use FileRefs* methods instead of manipulating directly
private PBXGroupSection groups = null; // use Groups* methods instead of manipulating directly
public PBXContainerItemProxySection containerItems = null;
public PBXReferenceProxySection references = null;
public PBXSourcesBuildPhaseSection sources = null;
public PBXFrameworksBuildPhaseSection frameworks = null;
public PBXResourcesBuildPhaseSection resources = null;
public PBXCopyFilesBuildPhaseSection copyFiles = null;
public PBXShellScriptBuildPhaseSection shellScripts = null;
public PBXNativeTargetSection nativeTargets = null;
public PBXTargetDependencySection targetDependencies = null;
public PBXVariantGroupSection variantGroups = null;
public XCBuildConfigurationSection buildConfigs = null;
public XCConfigurationListSection buildConfigLists = null;
public PBXProjectSection project = null;
// FIXME: create a separate PBXObject tree to represent these relationships
// A build file can be represented only once in all *BuildPhaseSection sections, thus
// we can simplify the cache by not caring about the file extension
private Dictionary<string, Dictionary<string, PBXBuildFileData>> m_FileGuidToBuildFileMap = null;
private Dictionary<string, PBXFileReferenceData> m_ProjectPathToFileRefMap = null;
private Dictionary<string, string> m_FileRefGuidToProjectPathMap = null;
private Dictionary<PBXSourceTree, Dictionary<string, PBXFileReferenceData>> m_RealPathToFileRefMap = null;
private Dictionary<string, PBXGroupData> m_ProjectPathToGroupMap = null;
private Dictionary<string, string> m_GroupGuidToProjectPathMap = null;
private Dictionary<string, PBXGroupData> m_GuidToParentGroupMap = null;
public PBXBuildFileData BuildFilesGet(string guid)
{
return buildFiles[guid];
}
// targetGuid is the guid of the target that contains the section that contains the buildFile
public void BuildFilesAdd(string targetGuid, PBXBuildFileData buildFile)
{
if (!m_FileGuidToBuildFileMap.ContainsKey(targetGuid))
m_FileGuidToBuildFileMap[targetGuid] = new Dictionary<string, PBXBuildFileData>();
m_FileGuidToBuildFileMap[targetGuid][buildFile.fileRef] = buildFile;
buildFiles.AddEntry(buildFile);
}
public void BuildFilesRemove(string targetGuid, string fileGuid)
{
var buildFile = BuildFilesGetForSourceFile(targetGuid, fileGuid);
if (buildFile != null)
{
m_FileGuidToBuildFileMap[targetGuid].Remove(buildFile.fileRef);
buildFiles.RemoveEntry(buildFile.guid);
}
}
public PBXBuildFileData BuildFilesGetForSourceFile(string targetGuid, string fileGuid)
{
if (!m_FileGuidToBuildFileMap.ContainsKey(targetGuid))
return null;
if (!m_FileGuidToBuildFileMap[targetGuid].ContainsKey(fileGuid))
return null;
return m_FileGuidToBuildFileMap[targetGuid][fileGuid];
}
public IEnumerable<PBXBuildFileData> BuildFilesGetAll()
{
return buildFiles.GetObjects();
}
public void FileRefsAdd(string realPath, string projectPath, PBXGroupData parent, PBXFileReferenceData fileRef)
{
fileRefs.AddEntry(fileRef);
m_ProjectPathToFileRefMap.Add(projectPath, fileRef);
m_FileRefGuidToProjectPathMap.Add(fileRef.guid, projectPath);
//m_RealPathToFileRefMap[fileRef.tree].Add(realPath, fileRef); // FIXME
if (m_RealPathToFileRefMap.ContainsKey (fileRef.tree))
m_RealPathToFileRefMap [fileRef.tree].Add (realPath, fileRef); // FIXME
m_GuidToParentGroupMap.Add(fileRef.guid, parent);
}
public IEnumerable<PBXFileReferenceData> FileRefsGetAll ()
{
return fileRefs.GetObjects();
}
public PBXFileReferenceData FileRefsGet(string guid)
{
return fileRefs[guid];
}
public PBXFileReferenceData FileRefsGetByRealPath(string path, PBXSourceTree sourceTree)
{
if (m_RealPathToFileRefMap[sourceTree].ContainsKey(path))
return m_RealPathToFileRefMap[sourceTree][path];
return null;
}
public PBXFileReferenceData FileRefsGetByProjectPath(string path)
{
if (m_ProjectPathToFileRefMap.ContainsKey(path))
return m_ProjectPathToFileRefMap[path];
return null;
}
public void FileRefsRemove(string guid)
{
PBXFileReferenceData fileRef = fileRefs[guid];
fileRefs.RemoveEntry(guid);
m_ProjectPathToFileRefMap.Remove(m_FileRefGuidToProjectPathMap[guid]);
m_FileRefGuidToProjectPathMap.Remove(guid);
foreach (var tree in FileTypeUtils.AllAbsoluteSourceTrees())
m_RealPathToFileRefMap[tree].Remove(fileRef.path);
m_GuidToParentGroupMap.Remove(guid);
}
public PBXGroupData GroupsGet(string guid)
{
return groups[guid];
}
public PBXGroupData GroupsGetByChild(string childGuid)
{
return m_GuidToParentGroupMap[childGuid];
}
public PBXGroupData GroupsGetMainGroup()
{
return groups[project.project.mainGroup];
}
/// Returns the source group identified by sourceGroup. If sourceGroup is empty or null,
/// root group is returned. If no group is found, null is returned.
public PBXGroupData GroupsGetByProjectPath(string sourceGroup)
{
if (m_ProjectPathToGroupMap.ContainsKey(sourceGroup))
return m_ProjectPathToGroupMap[sourceGroup];
return null;
}
public void GroupsAdd(string projectPath, PBXGroupData parent, PBXGroupData gr)
{
m_ProjectPathToGroupMap.Add(projectPath, gr);
m_GroupGuidToProjectPathMap.Add(gr.guid, projectPath);
m_GuidToParentGroupMap.Add(gr.guid, parent);
groups.AddEntry(gr);
}
public void GroupsAddDuplicate(PBXGroupData gr)
{
groups.AddEntry(gr);
}
public void GroupsRemove(string guid)
{
m_ProjectPathToGroupMap.Remove(m_GroupGuidToProjectPathMap[guid]);
m_GroupGuidToProjectPathMap.Remove(guid);
m_GuidToParentGroupMap.Remove(guid);
groups.RemoveEntry(guid);
}
public FileGUIDListBase BuildSectionAny(PBXNativeTargetData target, string path, bool isFolderRef)
{
string ext = Path.GetExtension(path);
var phase = FileTypeUtils.GetFileType(ext, isFolderRef);
switch (phase) {
case PBXFileType.Framework:
foreach (var guid in target.phases)
if (frameworks.HasEntry(guid))
return frameworks[guid];
break;
case PBXFileType.Resource:
foreach (var guid in target.phases)
if (resources.HasEntry(guid))
return resources[guid];
break;
case PBXFileType.Source:
foreach (var guid in target.phases)
if (sources.HasEntry(guid))
return sources[guid];
break;
case PBXFileType.CopyFile:
foreach (var guid in target.phases)
if (copyFiles.HasEntry(guid))
return copyFiles[guid];
break;
}
return null;
}
public FileGUIDListBase BuildSectionAny(string sectionGuid)
{
if (frameworks.HasEntry(sectionGuid))
return frameworks[sectionGuid];
if (resources.HasEntry(sectionGuid))
return resources[sectionGuid];
if (sources.HasEntry(sectionGuid))
return sources[sectionGuid];
if (copyFiles.HasEntry(sectionGuid))
return copyFiles[sectionGuid];
throw new Exception(String.Format("The given GUID {0} does not refer to a known build section", sectionGuid));
}
void RefreshBuildFilesMapForBuildFileGuidList(Dictionary<string, PBXBuildFileData> mapForTarget,
FileGUIDListBase list)
{
foreach (string guid in list.files)
{
var buildFile = buildFiles[guid];
mapForTarget[buildFile.fileRef] = buildFile;
}
}
void RefreshMapsForGroupChildren(string projectPath, string realPath, PBXSourceTree realPathTree, PBXGroupData parent)
{
var children = new List<string>(parent.children);
foreach (string guid in children)
{
PBXFileReferenceData fileRef = fileRefs[guid];
string pPath;
string rPath;
PBXSourceTree rTree;
if (fileRef != null)
{
pPath = PBXPath.Combine(projectPath, fileRef.name);
PBXPath.Combine(realPath, realPathTree, fileRef.path, fileRef.tree, out rPath, out rTree);
if (!m_ProjectPathToFileRefMap.ContainsKey(pPath))
{
m_ProjectPathToFileRefMap.Add(pPath, fileRef);
}
if (!m_FileRefGuidToProjectPathMap.ContainsKey(fileRef.guid))
{
m_FileRefGuidToProjectPathMap.Add(fileRef.guid, pPath);
}
if (!m_RealPathToFileRefMap[rTree].ContainsKey(rPath))
{
m_RealPathToFileRefMap[rTree].Add(rPath, fileRef);
}
if (!m_GuidToParentGroupMap.ContainsKey(guid))
{
m_GuidToParentGroupMap.Add(guid, parent);
}
continue;
}
PBXGroupData gr = groups[guid];
if (gr != null)
{
pPath = PBXPath.Combine(projectPath, gr.name);
PBXPath.Combine(realPath, realPathTree, gr.path, gr.tree, out rPath, out rTree);
if (!m_ProjectPathToGroupMap.ContainsKey(pPath))
{
m_ProjectPathToGroupMap.Add(pPath, gr);
}
if (!m_GroupGuidToProjectPathMap.ContainsKey(gr.guid))
{
m_GroupGuidToProjectPathMap.Add(gr.guid, pPath);
}
if (!m_GuidToParentGroupMap.ContainsKey(guid))
{
m_GuidToParentGroupMap.Add(guid, parent);
}
RefreshMapsForGroupChildren(pPath, rPath, rTree, gr);
}
}
}
void RefreshAuxMaps()
{
foreach (var targetEntry in nativeTargets.GetEntries())
{
var map = new Dictionary<string, PBXBuildFileData>();
foreach (string phaseGuid in targetEntry.Value.phases)
{
if (frameworks.HasEntry(phaseGuid))
RefreshBuildFilesMapForBuildFileGuidList(map, frameworks[phaseGuid]);
if (resources.HasEntry(phaseGuid))
RefreshBuildFilesMapForBuildFileGuidList(map, resources[phaseGuid]);
if (sources.HasEntry(phaseGuid))
RefreshBuildFilesMapForBuildFileGuidList(map, sources[phaseGuid]);
if (copyFiles.HasEntry(phaseGuid))
RefreshBuildFilesMapForBuildFileGuidList(map, copyFiles[phaseGuid]);
}
m_FileGuidToBuildFileMap[targetEntry.Key] = map;
}
RefreshMapsForGroupChildren("", "", PBXSourceTree.Source, GroupsGetMainGroup());
}
public void Clear()
{
buildFiles = new PBXBuildFileSection("PBXBuildFile");
fileRefs = new PBXFileReferenceSection("PBXFileReference");
groups = new PBXGroupSection("PBXGroup");
containerItems = new PBXContainerItemProxySection("PBXContainerItemProxy");
references = new PBXReferenceProxySection("PBXReferenceProxy");
sources = new PBXSourcesBuildPhaseSection("PBXSourcesBuildPhase");
frameworks = new PBXFrameworksBuildPhaseSection("PBXFrameworksBuildPhase");
resources = new PBXResourcesBuildPhaseSection("PBXResourcesBuildPhase");
copyFiles = new PBXCopyFilesBuildPhaseSection("PBXCopyFilesBuildPhase");
shellScripts = new PBXShellScriptBuildPhaseSection("PBXShellScriptBuildPhase");
nativeTargets = new PBXNativeTargetSection("PBXNativeTarget");
targetDependencies = new PBXTargetDependencySection("PBXTargetDependency");
variantGroups = new PBXVariantGroupSection("PBXVariantGroup");
buildConfigs = new XCBuildConfigurationSection("XCBuildConfiguration");
buildConfigLists = new XCConfigurationListSection("XCConfigurationList");
project = new PBXProjectSection();
m_UnknownSections = new Dictionary<string, UnknownSection>();
m_Section = new Dictionary<string, SectionBase>
{
{ "PBXBuildFile", buildFiles },
{ "PBXFileReference", fileRefs },
{ "PBXGroup", groups },
{ "PBXContainerItemProxy", containerItems },
{ "PBXReferenceProxy", references },
{ "PBXSourcesBuildPhase", sources },
{ "PBXFrameworksBuildPhase", frameworks },
{ "PBXResourcesBuildPhase", resources },
{ "PBXCopyFilesBuildPhase", copyFiles },
{ "PBXShellScriptBuildPhase", shellScripts },
{ "PBXNativeTarget", nativeTargets },
{ "PBXTargetDependency", targetDependencies },
{ "PBXVariantGroup", variantGroups },
{ "XCBuildConfiguration", buildConfigs },
{ "XCConfigurationList", buildConfigLists },
{ "PBXProject", project },
};
m_RootElements = new PBXElementDict();
m_UnknownObjects = new PBXElementDict();
m_ObjectVersion = null;
m_SectionOrder = new List<string>{
"PBXBuildFile", "PBXContainerItemProxy", "PBXCopyFilesBuildPhase", "PBXFileReference",
"PBXFrameworksBuildPhase", "PBXGroup", "PBXNativeTarget", "PBXProject", "PBXReferenceProxy",
"PBXResourcesBuildPhase", "PBXShellScriptBuildPhase", "PBXSourcesBuildPhase", "PBXTargetDependency",
"PBXVariantGroup", "XCBuildConfiguration", "XCConfigurationList"
};
m_FileGuidToBuildFileMap = new Dictionary<string, Dictionary<string, PBXBuildFileData>>();
m_ProjectPathToFileRefMap = new Dictionary<string, PBXFileReferenceData>();
m_FileRefGuidToProjectPathMap = new Dictionary<string, string>();
m_RealPathToFileRefMap = new Dictionary<PBXSourceTree, Dictionary<string, PBXFileReferenceData>>();
foreach (var tree in FileTypeUtils.AllAbsoluteSourceTrees())
m_RealPathToFileRefMap.Add(tree, new Dictionary<string, PBXFileReferenceData>());
m_ProjectPathToGroupMap = new Dictionary<string, PBXGroupData>();
m_GroupGuidToProjectPathMap = new Dictionary<string, string>();
m_GuidToParentGroupMap = new Dictionary<string, PBXGroupData>();
}
private void BuildCommentMapForBuildFiles(GUIDToCommentMap comments, List<string> guids, string sectName)
{
foreach (var guid in guids)
{
var buildFile = BuildFilesGet(guid);
if (buildFile != null)
{
var fileRef = FileRefsGet(buildFile.fileRef);
if (fileRef != null)
comments.Add(guid, String.Format("{0} in {1}", fileRef.name, sectName));
else
{
var reference = references[buildFile.fileRef];
if (reference != null)
comments.Add(guid, String.Format("{0} in {1}", reference.path, sectName));
}
}
}
}
private GUIDToCommentMap BuildCommentMap()
{
GUIDToCommentMap comments = new GUIDToCommentMap();
// buildFiles are handled below
// filerefs are handled below
foreach (var e in groups.GetObjects())
comments.Add(e.guid, e.name);
foreach (var e in containerItems.GetObjects())
comments.Add(e.guid, "PBXContainerItemProxy");
foreach (var e in references.GetObjects())
comments.Add(e.guid, e.path);
foreach (var e in sources.GetObjects())
{
comments.Add(e.guid, "Sources");
BuildCommentMapForBuildFiles(comments, e.files, "Sources");
}
foreach (var e in resources.GetObjects())
{
comments.Add(e.guid, "Resources");
BuildCommentMapForBuildFiles(comments, e.files, "Resources");
}
foreach (var e in frameworks.GetObjects())
{
comments.Add(e.guid, "Frameworks");
BuildCommentMapForBuildFiles(comments, e.files, "Frameworks");
}
foreach (var e in copyFiles.GetObjects())
{
string sectName = e.name;
if (sectName == null)
sectName = "CopyFiles";
comments.Add(e.guid, sectName);
BuildCommentMapForBuildFiles(comments, e.files, sectName);
}
foreach (var e in shellScripts.GetObjects())
comments.Add(e.guid, "ShellScript");
foreach (var e in targetDependencies.GetObjects())
comments.Add(e.guid, "PBXTargetDependency");
foreach (var e in nativeTargets.GetObjects())
{
comments.Add(e.guid, e.name);
comments.Add(e.buildConfigList, String.Format("Build configuration list for PBXNativeTarget \"{0}\"", e.name));
}
foreach (var e in variantGroups.GetObjects())
comments.Add(e.guid, e.name);
foreach (var e in buildConfigs.GetObjects())
comments.Add(e.guid, e.name);
foreach (var e in project.GetObjects())
{
comments.Add(e.guid, "Project object");
comments.Add(e.buildConfigList, "Build configuration list for PBXProject \"Unity-iPhone\""); // FIXME: project name is hardcoded
}
foreach (var e in fileRefs.GetObjects())
comments.Add(e.guid, e.name);
if (m_RootElements.Contains("rootObject") && m_RootElements["rootObject"] is PBXElementString)
comments.Add(m_RootElements["rootObject"].AsString(), "Project object");
return comments;
}
private static PBXElementDict ParseContent(string content)
{
TokenList tokens = Lexer.Tokenize(content);
var parser = new Parser(tokens);
TreeAST ast = parser.ParseTree();
return Serializer.ParseTreeAST(ast, tokens, content);
}
public void ReadFromStream(TextReader sr)
{
Clear();
m_RootElements = ParseContent(sr.ReadToEnd());
if (!m_RootElements.Contains("objects"))
throw new Exception("Invalid PBX project file: no objects element");
var objects = m_RootElements["objects"].AsDict();
m_RootElements.Remove("objects");
m_RootElements.SetString("objects", "OBJMARKER");
if (m_RootElements.Contains("objectVersion"))
{
m_ObjectVersion = m_RootElements["objectVersion"].AsString();
m_RootElements.Remove("objectVersion");
}
var allGuids = new List<string>();
string prevSectionName = null;
foreach (var kv in objects.values)
{
allGuids.Add(kv.Key);
var el = kv.Value;
if (!(el is PBXElementDict) || !el.AsDict().Contains("isa"))
{
m_UnknownObjects.values.Add(kv.Key, el);
continue;
}
var dict = el.AsDict();
var sectionName = dict["isa"].AsString();
if (m_Section.ContainsKey(sectionName))
{
var section = m_Section[sectionName];
section.AddObject(kv.Key, dict);
}
else
{
UnknownSection section;
if (m_UnknownSections.ContainsKey(sectionName))
section = m_UnknownSections[sectionName];
else
{
section = new UnknownSection(sectionName);
m_UnknownSections.Add(sectionName, section);
}
section.AddObject(kv.Key, dict);
// update section order
if (!m_SectionOrder.Contains(sectionName))
{
int pos = 0;
if (prevSectionName != null)
{
// this never fails, because we already added any previous unknown sections
// to m_SectionOrder
pos = m_SectionOrder.FindIndex(x => x == prevSectionName);
pos += 1;
}
m_SectionOrder.Insert(pos, sectionName);
}
}
prevSectionName = sectionName;
}
RepairStructure(allGuids);
RefreshAuxMaps();
}
public string WriteToString()
{
var commentMap = BuildCommentMap();
var emptyChecker = new PropertyCommentChecker();
var emptyCommentMap = new GUIDToCommentMap();
// since we need to add custom comments, the serialization is much more complex
StringBuilder objectsSb = new StringBuilder();
if (m_ObjectVersion != null) // objectVersion comes right before objects
objectsSb.AppendFormat("objectVersion = {0};\n\t", m_ObjectVersion);
objectsSb.Append("objects = {");
foreach (string sectionName in m_SectionOrder)
{
if (m_Section.ContainsKey(sectionName))
m_Section[sectionName].WriteSection(objectsSb, commentMap);
else if (m_UnknownSections.ContainsKey(sectionName))
m_UnknownSections[sectionName].WriteSection(objectsSb, commentMap);
}
foreach (var kv in m_UnknownObjects.values)
Serializer.WriteDictKeyValue(objectsSb, kv.Key, kv.Value, 2, false, emptyChecker, emptyCommentMap);
objectsSb.Append("\n\t};");
StringBuilder contentSb = new StringBuilder();
contentSb.Append("// !$*UTF8*$!\n");
Serializer.WriteDict(contentSb, m_RootElements, 0, false,
new PropertyCommentChecker(new string[]{"rootObject/*"}), commentMap);
contentSb.Append("\n");
string content = contentSb.ToString();
content = content.Replace("objects = OBJMARKER;", objectsSb.ToString());
return content;
}
// This method walks the project structure and removes invalid entries.
void RepairStructure(List<string> allGuids)
{
var guidSet = new Dictionary<string, bool>(); // emulate HashSet on .Net 2.0
foreach (var guid in allGuids)
guidSet.Add(guid, false);
while (RepairStructureImpl(guidSet) == true)
;
}
/* Iterates the given guid list and removes all guids that are not in allGuids dictionary.
*/
static void RemoveMissingGuidsFromGuidList(PBX.GUIDList guidList, Dictionary<string, bool> allGuids)
{
List<string> guidsToRemove = null;
foreach (var guid in guidList)
{
if (!allGuids.ContainsKey(guid))
{
if (guidsToRemove == null)
guidsToRemove = new List<string>();
guidsToRemove.Add(guid);
}
}
if (guidsToRemove != null)
{
foreach (var guid in guidsToRemove)
guidList.RemoveGUID(guid);
}
}
/* Removes objects from the given @a section for which @a checker returns true.
Also removes the guids of the removed elements from allGuids dictionary.
Returns true if any objects were removed.
*/
static bool RemoveObjectsFromSection<T>(KnownSectionBase<T> section,
Dictionary<string, bool> allGuids,
Func<T, bool> checker) where T : PBXObjectData, new()
{
List<string> guidsToRemove = null;
foreach (var kv in section.GetEntries())
{
if (checker(kv.Value))
{
if (guidsToRemove == null)
guidsToRemove = new List<string>();
guidsToRemove.Add(kv.Key);
}
}
if (guidsToRemove != null)
{
foreach (var guid in guidsToRemove)
{
section.RemoveEntry(guid);
allGuids.Remove(guid);
}
return true;
}
return false;
}
// Returns true if changes were done and one should call RepairStructureImpl again
bool RepairStructureImpl(Dictionary<string, bool> allGuids)
{
bool changed = false;
// PBXBuildFile
changed |= RemoveObjectsFromSection(buildFiles, allGuids,
o => (o.fileRef == null || !allGuids.ContainsKey(o.fileRef)));
// PBXFileReference / fileRefs not cleaned
// PBXGroup
changed |= RemoveObjectsFromSection(groups, allGuids, o => o.children == null);
foreach (var o in groups.GetObjects())
RemoveMissingGuidsFromGuidList(o.children, allGuids);
// PBXContainerItem / containerItems not cleaned
// PBXReferenceProxy / references not cleaned
// PBXSourcesBuildPhase
changed |= RemoveObjectsFromSection(sources, allGuids, o => o.files == null);
foreach (var o in sources.GetObjects())
RemoveMissingGuidsFromGuidList(o.files, allGuids);
// PBXFrameworksBuildPhase
changed |= RemoveObjectsFromSection(frameworks, allGuids, o => o.files == null);
foreach (var o in frameworks.GetObjects())
RemoveMissingGuidsFromGuidList(o.files, allGuids);
// PBXResourcesBuildPhase
changed |= RemoveObjectsFromSection(resources, allGuids, o => o.files == null);
foreach (var o in resources.GetObjects())
RemoveMissingGuidsFromGuidList(o.files, allGuids);
// PBXCopyFilesBuildPhase
changed |= RemoveObjectsFromSection(copyFiles, allGuids, o => o.files == null);
foreach (var o in copyFiles.GetObjects())
RemoveMissingGuidsFromGuidList(o.files, allGuids);
// PBXShellScriptsBuildPhase
changed |= RemoveObjectsFromSection(shellScripts, allGuids, o => o.files == null);
foreach (var o in shellScripts.GetObjects())
RemoveMissingGuidsFromGuidList(o.files, allGuids);
// PBXNativeTarget
changed |= RemoveObjectsFromSection(nativeTargets, allGuids, o => o.phases == null);
foreach (var o in nativeTargets.GetObjects())
RemoveMissingGuidsFromGuidList(o.phases, allGuids);
// PBXTargetDependency / targetDependencies not cleaned
// PBXVariantGroup
changed |= RemoveObjectsFromSection(variantGroups, allGuids, o => o.children == null);
foreach (var o in variantGroups.GetObjects())
RemoveMissingGuidsFromGuidList(o.children, allGuids);
// XCBuildConfiguration / buildConfigs not cleaned
// XCConfigurationList
changed |= RemoveObjectsFromSection(buildConfigLists, allGuids, o => o.buildConfigs == null);
foreach (var o in buildConfigLists.GetObjects())
RemoveMissingGuidsFromGuidList(o.buildConfigs, allGuids);
// PBXProject project not cleaned
return changed;
}
public PBXGroupData GroupsGetByName (string name)
{
foreach (var group in groups.GetEntries())
if (group.Value.name == name)
return group.Value;
return null;
}
}
} // namespace UnityEditor.iOS.Xcode
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 54c86bc46b87645c78e5b211a0eeada5
timeCreated: 1496741691
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+296
View File
@@ -0,0 +1,296 @@
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System;
using ChillyRoom.UnityEditor.iOS.Xcode.PBX;
namespace ChillyRoom.UnityEditor.iOS.Xcode.Extensions
{
/* This class implements a number of static methods for performing common tasks
on xcode projects.
TODO: Make sure enough stuff is exposed so that it's possible to perform the tasks
without using internal APIs
*/
public static class PBXProjectExtensions
{
// Create a wrapper class so that collection initializers work and we can have a
// compact notation. Note that we can't use Dictionary because the keys may be duplicate
internal class FlagList : List<KeyValuePair<string, string>>
{
public void Add(string flag, string value)
{
Add(new KeyValuePair<string, string>(flag, value));
}
}
internal static FlagList appExtensionReleaseBuildFlags = new FlagList
{
// { "INFOPLIST_FILE", <path/to/info.plist> },
{ "LD_RUNPATH_SEARCH_PATHS", "$(inherited)" },
{ "LD_RUNPATH_SEARCH_PATHS", "@executable_path/Frameworks" },
{ "LD_RUNPATH_SEARCH_PATHS", "@executable_path/../../Frameworks" },
// { "PRODUCT_BUNDLE_IDENTIFIER", "<bundle id>" },
{ "PRODUCT_NAME", "$(TARGET_NAME)" },
{ "SKIP_INSTALL", "YES" },
};
internal static FlagList appExtensionDebugBuildFlags = new FlagList
{
// { "INFOPLIST_FILE", <path/to/info.plist> },
{ "LD_RUNPATH_SEARCH_PATHS", "$(inherited)" },
{ "LD_RUNPATH_SEARCH_PATHS", "@executable_path/Frameworks" },
{ "LD_RUNPATH_SEARCH_PATHS", "@executable_path/../../Frameworks" },
// { "PRODUCT_BUNDLE_IDENTIFIER", "<bundle id>" },
{ "PRODUCT_NAME", "$(TARGET_NAME)" },
{ "SKIP_INSTALL", "YES" },
};
internal static FlagList watchExtensionReleaseBuildFlags = new FlagList
{
{ "ASSETCATALOG_COMPILER_COMPLICATION_NAME", "Complication" },
{ "CLANG_ANALYZER_NONNULL", "YES" },
{ "CLANG_WARN_DOCUMENTATION_COMMENTS", "YES" },
{ "CLANG_WARN_INFINITE_RECURSION", "YES" },
{ "CLANG_WARN_SUSPICIOUS_MOVE", "YES" },
{ "DEBUG_INFORMATION_FORMAT", "dwarf-with-dsym" },
{ "GCC_NO_COMMON_BLOCKS", "YES" },
//{ "INFOPLIST_FILE", "<path/to/Info.plist>" },
{ "LD_RUNPATH_SEARCH_PATHS", "$(inherited)" },
{ "LD_RUNPATH_SEARCH_PATHS", "@executable_path/Frameworks" },
{ "LD_RUNPATH_SEARCH_PATHS", "@executable_path/../../Frameworks" },
// { "PRODUCT_BUNDLE_IDENTIFIER", "<bundle id>" },
{ "PRODUCT_NAME", "${TARGET_NAME}" },
{ "SDKROOT", "watchos" },
{ "SKIP_INSTALL", "YES" },
{ "TARGETED_DEVICE_FAMILY", "4" },
{ "WATCHOS_DEPLOYMENT_TARGET", "3.1" },
// the following are needed to override project settings in Unity Xcode project
{ "ARCHS", "$(ARCHS_STANDARD)" },
{ "SUPPORTED_PLATFORMS", "watchos" },
{ "SUPPORTED_PLATFORMS", "watchsimulator" },
};
internal static FlagList watchExtensionDebugBuildFlags = new FlagList
{
{ "ASSETCATALOG_COMPILER_COMPLICATION_NAME", "Complication" },
{ "CLANG_ANALYZER_NONNULL", "YES" },
{ "CLANG_WARN_DOCUMENTATION_COMMENTS", "YES" },
{ "CLANG_WARN_INFINITE_RECURSION", "YES" },
{ "CLANG_WARN_SUSPICIOUS_MOVE", "YES" },
{ "DEBUG_INFORMATION_FORMAT", "dwarf" },
{ "ENABLE_TESTABILITY", "YES" },
{ "GCC_NO_COMMON_BLOCKS", "YES" },
// { "INFOPLIST_FILE", "<path/to/Info.plist>" },
{ "LD_RUNPATH_SEARCH_PATHS", "$(inherited)" },
{ "LD_RUNPATH_SEARCH_PATHS", "@executable_path/Frameworks" },
{ "LD_RUNPATH_SEARCH_PATHS", "@executable_path/../../Frameworks" },
// { "PRODUCT_BUNDLE_IDENTIFIER", "<bundle id>" },
{ "PRODUCT_NAME", "${TARGET_NAME}" },
{ "SDKROOT", "watchos" },
{ "SKIP_INSTALL", "YES" },
{ "TARGETED_DEVICE_FAMILY", "4" },
{ "WATCHOS_DEPLOYMENT_TARGET", "3.1" },
// the following are needed to override project settings in Unity Xcode project
{ "ARCHS", "$(ARCHS_STANDARD)" },
{ "SUPPORTED_PLATFORMS", "watchos" },
{ "SUPPORTED_PLATFORMS", "watchsimulator" },
};
internal static FlagList watchAppReleaseBuildFlags = new FlagList
{
{ "ASSETCATALOG_COMPILER_APPICON_NAME", "AppIcon" },
{ "CLANG_ANALYZER_NONNULL", "YES" },
{ "CLANG_WARN_DOCUMENTATION_COMMENTS", "YES" },
{ "CLANG_WARN_INFINITE_RECURSION", "YES" },
{ "CLANG_WARN_SUSPICIOUS_MOVE", "YES" },
{ "DEBUG_INFORMATION_FORMAT", "dwarf-with-dsym" },
{ "GCC_NO_COMMON_BLOCKS", "YES" },
//{ "IBSC_MODULE", "the extension target name with ' ' replaced with '_'" },
//{ "INFOPLIST_FILE", "<path/to/Info.plist>" },
//{ "PRODUCT_BUNDLE_IDENTIFIER", "<bundle id>" },
{ "PRODUCT_NAME", "$(TARGET_NAME)" },
{ "SDKROOT", "watchos" },
{ "SKIP_INSTALL", "YES" },
{ "TARGETED_DEVICE_FAMILY", "4" },
{ "WATCHOS_DEPLOYMENT_TARGET", "3.1" },
// the following are needed to override project settings in Unity Xcode project
{ "ARCHS", "$(ARCHS_STANDARD)" },
{ "SUPPORTED_PLATFORMS", "watchos" },
{ "SUPPORTED_PLATFORMS", "watchsimulator" },
};
internal static FlagList watchAppDebugBuildFlags = new FlagList
{
{ "ASSETCATALOG_COMPILER_APPICON_NAME", "AppIcon" },
{ "CLANG_ANALYZER_NONNULL", "YES" },
{ "CLANG_WARN_DOCUMENTATION_COMMENTS", "YES" },
{ "CLANG_WARN_INFINITE_RECURSION", "YES" },
{ "CLANG_WARN_SUSPICIOUS_MOVE", "YES" },
{ "DEBUG_INFORMATION_FORMAT", "dwarf" },
{ "ENABLE_TESTABILITY", "YES" },
{ "GCC_NO_COMMON_BLOCKS", "YES" },
//{ "IBSC_MODULE", "the extension target name with ' ' replaced with '_'" },
//{ "INFOPLIST_FILE", "<path/to/Info.plist>" },
//{ "PRODUCT_BUNDLE_IDENTIFIER", "<bundle id>" },
{ "PRODUCT_NAME", "$(TARGET_NAME)" },
{ "SDKROOT", "watchos" },
{ "SKIP_INSTALL", "YES" },
{ "TARGETED_DEVICE_FAMILY", "4" },
{ "WATCHOS_DEPLOYMENT_TARGET", "3.1" },
// the following are needed to override project settings in Unity Xcode project
{ "ARCHS", "$(ARCHS_STANDARD)" },
{ "SUPPORTED_PLATFORMS", "watchos" },
{ "SUPPORTED_PLATFORMS", "watchsimulator" },
};
static void SetBuildFlagsFromDict(this PBXProject proj, string configGuid, IEnumerable<KeyValuePair<string, string>> data)
{
foreach (var kv in data)
proj.AddBuildPropertyForConfig(configGuid, kv.Key, kv.Value);
}
internal static void SetDefaultAppExtensionReleaseBuildFlags(this PBXProject proj, string configGuid)
{
SetBuildFlagsFromDict(proj, configGuid, appExtensionReleaseBuildFlags);
}
internal static void SetDefaultAppExtensionDebugBuildFlags(this PBXProject proj, string configGuid)
{
SetBuildFlagsFromDict(proj, configGuid, appExtensionDebugBuildFlags);
}
internal static void SetDefaultWatchExtensionReleaseBuildFlags(this PBXProject proj, string configGuid)
{
SetBuildFlagsFromDict(proj, configGuid, watchExtensionReleaseBuildFlags);
}
internal static void SetDefaultWatchExtensionDebugBuildFlags(this PBXProject proj, string configGuid)
{
SetBuildFlagsFromDict(proj, configGuid, watchExtensionDebugBuildFlags);
}
internal static void SetDefaultWatchAppReleaseBuildFlags(this PBXProject proj, string configGuid)
{
SetBuildFlagsFromDict(proj, configGuid, watchAppReleaseBuildFlags);
}
internal static void SetDefaultWatchAppDebugBuildFlags(this PBXProject proj, string configGuid)
{
SetBuildFlagsFromDict(proj, configGuid, watchAppDebugBuildFlags);
}
/// <summary>
/// Creates an app extension.
/// </summary>
/// <returns>The GUID of the new target.</returns>
/// <param name="proj">A project passed as this argument.</param>
/// <param name="mainTargetGuid">The GUID of the main target to link the app to.</param>
/// <param name="name">The name of the app extension.</param>
/// <param name="bundleId">The bundle ID of the app extension. The bundle ID must be
/// prefixed with the parent app bundle ID.</param>
/// <param name="infoPlistPath">Path to the app extension Info.plist document.</param>
public static string AddAppExtension(this PBXProject proj, string mainTargetGuid,
string name, string bundleId, string infoPlistPath)
{
string ext = ".appex";
var newTargetGuid = proj.AddTarget(name, ext, "com.apple.product-type.app-extension");
foreach (var configName in proj.BuildConfigNames())
{
var configGuid = proj.BuildConfigByName(newTargetGuid, configName);
if (configName.Contains("Debug"))
SetDefaultAppExtensionDebugBuildFlags(proj, configGuid);
else
SetDefaultAppExtensionReleaseBuildFlags(proj, configGuid);
proj.SetBuildPropertyForConfig(configGuid, "INFOPLIST_FILE", infoPlistPath);
proj.SetBuildPropertyForConfig(configGuid, "PRODUCT_BUNDLE_IDENTIFIER", bundleId);
}
proj.AddSourcesBuildPhase(newTargetGuid);
proj.AddResourcesBuildPhase(newTargetGuid);
proj.AddFrameworksBuildPhase(newTargetGuid);
string copyFilesPhaseGuid = proj.AddCopyFilesBuildPhase(mainTargetGuid, "Embed App Extensions", "", "13");
proj.AddFileToBuildSection(mainTargetGuid, copyFilesPhaseGuid, proj.GetTargetProductFileRef(newTargetGuid));
proj.AddTargetDependency(mainTargetGuid, newTargetGuid);
return newTargetGuid;
}
/// <summary>
/// Creates a watch application.
/// </summary>
/// <returns>The GUID of the new target.</returns>
/// <param name="proj">A project passed as this argument.</param>
/// <param name="mainTargetGuid">The GUID of the main target to link the watch app to.</param>
/// <param name="watchExtensionTargetGuid">The GUID of watch extension as returned by [[AddWatchExtension()]].</param>
/// <param name="name">The name of the watch app. It must the same as the name of the watch extension.</param>
/// <param name="bundleId">The bundle ID of the watch app.</param>
/// <param name="infoPlistPath">Path to the watch app Info.plist document.</param>
public static string AddWatchApp(this PBXProject proj, string mainTargetGuid, string watchExtensionTargetGuid,
string name, string bundleId, string infoPlistPath)
{
var newTargetGuid = proj.AddTarget(name, ".app", "com.apple.product-type.application.watchapp2");
var isbcModuleName = proj.nativeTargets[watchExtensionTargetGuid].name.Replace(" ", "_");
foreach (var configName in proj.BuildConfigNames())
{
var configGuid = proj.BuildConfigByName(newTargetGuid, configName);
if (configName.Contains("Debug"))
SetDefaultWatchAppDebugBuildFlags(proj, configGuid);
else
SetDefaultWatchAppReleaseBuildFlags(proj, configGuid);
proj.SetBuildPropertyForConfig(configGuid, "PRODUCT_BUNDLE_IDENTIFIER", bundleId);
proj.SetBuildPropertyForConfig(configGuid, "INFOPLIST_FILE", infoPlistPath);
proj.SetBuildPropertyForConfig(configGuid, "IBSC_MODULE", isbcModuleName);
}
proj.AddResourcesBuildPhase(newTargetGuid);
string copyFilesGuid = proj.AddCopyFilesBuildPhase(newTargetGuid, "Embed App Extensions", "", "13");
proj.AddFileToBuildSection(newTargetGuid, copyFilesGuid, proj.GetTargetProductFileRef(watchExtensionTargetGuid));
string copyWatchFilesGuid = proj.AddCopyFilesBuildPhase(mainTargetGuid, "Embed Watch Content", "$(CONTENTS_FOLDER_PATH)/Watch", "16");
proj.AddFileToBuildSection(mainTargetGuid, copyWatchFilesGuid, proj.GetTargetProductFileRef(newTargetGuid));
proj.AddTargetDependency(newTargetGuid, watchExtensionTargetGuid);
proj.AddTargetDependency(mainTargetGuid, newTargetGuid);
return newTargetGuid;
}
/// <summary>
/// Creates a watch extension.
/// </summary>
/// <returns>The GUID of the new target.</returns>
/// <param name="proj">A project passed as this argument.</param>
/// <param name="mainTarget">The GUID of the main target to link the watch extension to.</param>
/// <param name="name">The name of the watch extension.</param>
/// <param name="bundleId">The bundle ID of the watch extension. The bundle ID must be
/// prefixed with the parent watch app bundle ID.</param>
/// <param name="infoPlistPath">Path to the watch extension Info.plist document.</param>
public static string AddWatchExtension(this PBXProject proj, string mainTarget,
string name, string bundleId, string infoPlistPath)
{
var newTargetGuid = proj.AddTarget(name, ".appex", "com.apple.product-type.watchkit2-extension");
foreach (var configName in proj.BuildConfigNames())
{
var configGuid = proj.BuildConfigByName(newTargetGuid, configName);
if (configName.Contains("Debug"))
SetDefaultWatchExtensionDebugBuildFlags(proj, configGuid);
else
SetDefaultWatchExtensionReleaseBuildFlags(proj, configGuid);
proj.SetBuildPropertyForConfig(configGuid, "PRODUCT_BUNDLE_IDENTIFIER", bundleId);
proj.SetBuildPropertyForConfig(configGuid, "INFOPLIST_FILE", infoPlistPath);
}
proj.AddSourcesBuildPhase(newTargetGuid);
proj.AddResourcesBuildPhase(newTargetGuid);
proj.AddFrameworksBuildPhase(newTargetGuid);
return newTargetGuid;
}
}
} // namespace UnityEditor.iOS.Xcode
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: b84f17869f54f4d7a952c9f63e5744d6
timeCreated: 1496741691
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+351
View File
@@ -0,0 +1,351 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;
namespace ChillyRoom.UnityEditor.iOS.Xcode
{
public class PlistElement
{
protected PlistElement() {}
// convenience methods
public string AsString() { return ((PlistElementString)this).value; }
public int AsInteger() { return ((PlistElementInteger)this).value; }
public bool AsBoolean() { return ((PlistElementBoolean)this).value; }
public PlistElementArray AsArray() { return (PlistElementArray)this; }
public PlistElementDict AsDict() { return (PlistElementDict)this; }
public PlistElement this[string key]
{
get { return AsDict()[key]; }
set { AsDict()[key] = value; }
}
}
public class PlistElementString : PlistElement
{
public PlistElementString(string v) { value = v; }
public string value;
}
public class PlistElementInteger : PlistElement
{
public PlistElementInteger(int v) { value = v; }
public int value;
}
public class PlistElementBoolean : PlistElement
{
public PlistElementBoolean(bool v) { value = v; }
public bool value;
}
public class PlistElementDict : PlistElement
{
public PlistElementDict() : base() {}
private SortedDictionary<string, PlistElement> m_PrivateValue = new SortedDictionary<string, PlistElement>();
public IDictionary<string, PlistElement> values { get { return m_PrivateValue; }}
new public PlistElement this[string key]
{
get {
if (values.ContainsKey(key))
return values[key];
return null;
}
set { this.values[key] = value; }
}
// convenience methods
public void SetInteger(string key, int val)
{
values[key] = new PlistElementInteger(val);
}
public void SetString(string key, string val)
{
values[key] = new PlistElementString(val);
}
public void SetBoolean(string key, bool val)
{
values[key] = new PlistElementBoolean(val);
}
public PlistElementArray CreateArray(string key)
{
var v = new PlistElementArray();
values[key] = v;
return v;
}
public PlistElementDict CreateDict(string key)
{
var v = new PlistElementDict();
values[key] = v;
return v;
}
}
public class PlistElementArray : PlistElement
{
public PlistElementArray() : base() {}
public List<PlistElement> values = new List<PlistElement>();
// convenience methods
public void AddString(string val)
{
values.Add(new PlistElementString(val));
}
public void AddInteger(int val)
{
values.Add(new PlistElementInteger(val));
}
public void AddBoolean(bool val)
{
values.Add(new PlistElementBoolean(val));
}
public PlistElementArray AddArray()
{
var v = new PlistElementArray();
values.Add(v);
return v;
}
public PlistElementDict AddDict()
{
var v = new PlistElementDict();
values.Add(v);
return v;
}
}
public class PlistDocument
{
public PlistElementDict root;
public string version;
public PlistDocument()
{
root = new PlistElementDict();
version = "1.0";
}
// Parses a string that contains a XML file. No validation is done.
internal static XDocument ParseXmlNoDtd(string text)
{
XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;
settings.XmlResolver = null; // prevent DTD download
XmlReader xmlReader = XmlReader.Create(new StringReader(text), settings);
return XDocument.Load(xmlReader);
}
// LINQ serializes XML DTD declaration with an explicit empty 'internal subset'
// (a pair of square brackets at the end of Doctype declaration).
// Even though this is valid XML, XCode does not like it, hence this workaround.
internal static string CleanDtdToString(XDocument doc)
{
// LINQ does not support changing the DTD of existing XDocument instances,
// so we create a dummy document for printing of the Doctype declaration.
// A single dummy element is added to force LINQ not to omit the declaration.
// Also, utf-8 encoding is forced since this is the encoding we use when writing to file in UpdateInfoPlist.
if (doc.DocumentType != null)
{
XDocument tmpDoc =
new XDocument(new XDeclaration("1.0", "utf-8", null),
new XDocumentType(doc.DocumentType.Name, doc.DocumentType.PublicId, doc.DocumentType.SystemId, null),
new XElement(doc.Root.Name));
return "" + tmpDoc.Declaration + "\n" + tmpDoc.DocumentType + "\n" + doc.Root;
}
else
{
XDocument tmpDoc = new XDocument(new XDeclaration("1.0", "utf-8", null), new XElement(doc.Root.Name));
return "" + tmpDoc.Declaration + Environment.NewLine + doc.Root;
}
}
private static string GetText(XElement xml)
{
return String.Join("", xml.Nodes().OfType<XText>().Select(x => x.Value).ToArray());
}
private static PlistElement ReadElement(XElement xml)
{
switch (xml.Name.LocalName)
{
case "dict":
{
List<XElement> children = xml.Elements().ToList();
var el = new PlistElementDict();
if (children.Count % 2 == 1)
throw new Exception("Malformed plist file");
for (int i = 0; i < children.Count - 1; i++)
{
if (children[i].Name != "key")
throw new Exception("Malformed plist file");
string key = GetText(children[i]).Trim();
var newChild = ReadElement(children[i+1]);
if (newChild != null)
{
i++;
el[key] = newChild;
}
}
return el;
}
case "array":
{
List<XElement> children = xml.Elements().ToList();
var el = new PlistElementArray();
foreach (var childXml in children)
{
var newChild = ReadElement(childXml);
if (newChild != null)
el.values.Add(newChild);
}
return el;
}
case "string":
return new PlistElementString(GetText(xml));
case "integer":
{
int r;
if (int.TryParse(GetText(xml), out r))
return new PlistElementInteger(r);
return null;
}
case "true":
return new PlistElementBoolean(true);
case "false":
return new PlistElementBoolean(false);
default:
return null;
}
}
public void Create()
{
const string doc = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">" +
"<plist version=\"1.0\">" +
"<dict>" +
"</dict>" +
"</plist>";
ReadFromString(doc);
}
public void ReadFromFile(string path)
{
ReadFromString(File.ReadAllText(path));
}
public void ReadFromStream(TextReader tr)
{
ReadFromString(tr.ReadToEnd());
}
public void ReadFromString(string text)
{
XDocument doc = ParseXmlNoDtd(text);
version = (string) doc.Root.Attribute("version");
XElement xml = doc.XPathSelectElement("plist/dict");
var dict = ReadElement(xml);
if (dict == null)
throw new Exception("Error parsing plist file");
root = dict as PlistElementDict;
if (root == null)
throw new Exception("Malformed plist file");
}
private static XElement WriteElement(PlistElement el)
{
if (el is PlistElementBoolean)
{
var realEl = el as PlistElementBoolean;
return new XElement(realEl.value ? "true" : "false");
}
if (el is PlistElementInteger)
{
var realEl = el as PlistElementInteger;
return new XElement("integer", realEl.value.ToString());
}
if (el is PlistElementString)
{
var realEl = el as PlistElementString;
return new XElement("string", realEl.value);
}
if (el is PlistElementDict)
{
var realEl = el as PlistElementDict;
var dictXml = new XElement("dict");
foreach (var kv in realEl.values)
{
var keyXml = new XElement("key", kv.Key);
var valueXml = WriteElement(kv.Value);
if (valueXml != null)
{
dictXml.Add(keyXml);
dictXml.Add(valueXml);
}
}
return dictXml;
}
if (el is PlistElementArray)
{
var realEl = el as PlistElementArray;
var arrayXml = new XElement("array");
foreach (var v in realEl.values)
{
var elXml = WriteElement(v);
if (elXml != null)
arrayXml.Add(elXml);
}
return arrayXml;
}
return null;
}
public void WriteToFile(string path)
{
System.Text.Encoding utf8WithoutBom = new System.Text.UTF8Encoding(false);
File.WriteAllText(path, WriteToString(), utf8WithoutBom);
}
public void WriteToStream(TextWriter tw)
{
tw.Write(WriteToString());
}
public string WriteToString()
{
var el = WriteElement(root);
var rootEl = new XElement("plist");
rootEl.Add(new XAttribute("version", version));
rootEl.Add(el);
var doc = new XDocument();
doc.Add(rootEl);
return CleanDtdToString(doc).Replace("\r\n", "\n");
}
}
} // namespace UnityEditor.iOS.XCode
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: c2ed9743fe9634c808ea1dc01c20e01e
timeCreated: 1496741691
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,578 @@
using System;
using System.IO;
namespace ChillyRoom.UnityEditor.iOS.Xcode
{
// This class is here to help you add capabilities to your Xcode project.
// Because capabilities modify the PBXProject, the entitlements file and/or the Info.plist and not consistently,
// it can be tedious.
// Therefore this class open the PBXProject that is always modify by capabilities and open Entitlement and info.plist only when needed.
// For optimisation reasons, we write the file only in the close method.
// If you don't call it the file will not be written.
public class ProjectCapabilityManager
{
private readonly string m_BuildPath;
private readonly string m_TargetGuid;
private readonly string m_PBXProjectPath;
private readonly string m_EntitlementFilePath;
private PlistDocument m_Entitlements;
private PlistDocument m_InfoPlist;
protected internal PBXProject project;
// Create the manager with the required parameter to open files and set the properties in the write place.
public ProjectCapabilityManager(string pbxProjectPath, string entitlementFilePath, string targetName)
{
m_BuildPath = Directory.GetParent(Path.GetDirectoryName(pbxProjectPath)).FullName;
m_EntitlementFilePath = entitlementFilePath;
m_PBXProjectPath = pbxProjectPath;
project = new PBXProject();
project.ReadFromString(File.ReadAllText(m_PBXProjectPath));
m_TargetGuid = project.TargetGuidByName(targetName);
}
// Write the actual file to the disk.
// If you don't call this method nothing will change.
public void WriteToFile()
{
File.WriteAllText(m_PBXProjectPath, project.WriteToString());
if (m_Entitlements != null)
m_Entitlements.WriteToFile(PBXPath.Combine(m_BuildPath, m_EntitlementFilePath));
if (m_InfoPlist != null)
m_InfoPlist.WriteToFile(PBXPath.Combine(m_BuildPath, "Info.plist"));
}
// Add the iCloud capability with the desired options.
public void AddiCloud(bool keyValueStorage, bool iCloudDocument, string[] customContainers)
{
var ent = GetOrCreateEntitlementDoc();
var val = (ent.root[ICloudEntitlements.ContainerIdValue] = new PlistElementArray()) as PlistElementArray;
if (iCloudDocument)
{
val.values.Add(new PlistElementString(ICloudEntitlements.ContainerIdValue));
var ser = (ent.root[ICloudEntitlements.ServicesKey] = new PlistElementArray()) as PlistElementArray;
ser.values.Add(new PlistElementString(ICloudEntitlements.ServicesKitValue));
ser.values.Add(new PlistElementString(ICloudEntitlements.ServicesDocValue));
var ubiquity = (ent.root[ICloudEntitlements.UbiquityContainerIdKey] = new PlistElementArray()) as PlistElementArray;
ubiquity.values.Add(new PlistElementString(ICloudEntitlements.UbiquityContainerIdValue));
for (var i = 0; i < customContainers.Length; i++)
{
ser.values.Add(new PlistElementString(customContainers[i]));
}
}
if (keyValueStorage)
{
ent.root[ICloudEntitlements.KeyValueStoreKey] = new PlistElementString(ICloudEntitlements.KeyValueStoreValue);
}
project.AddCapability(m_TargetGuid, PBXCapabilityType.iCloud, m_EntitlementFilePath, iCloudDocument);
}
// Add Push (or remote) Notifications capability to your project
public void AddPushNotifications(bool development)
{
GetOrCreateEntitlementDoc().root[PushNotificationEntitlements.Key] = new PlistElementString(development ? PushNotificationEntitlements.DevelopmentValue : PushNotificationEntitlements.ProductionValue);
project.AddCapability(m_TargetGuid, PBXCapabilityType.PushNotifications, m_EntitlementFilePath);
}
// Add GameCenter capability to the project.
public void AddGameCenter()
{
var arr = (GetOrCreateInfoDoc().root[GameCenterInfo.Key] ?? (GetOrCreateInfoDoc().root[GameCenterInfo.Key] = new PlistElementArray())) as PlistElementArray;
arr.values.Add(new PlistElementString(GameCenterInfo.Value));
project.AddCapability(m_TargetGuid, PBXCapabilityType.GameCenter);
}
// Add Wallet capability to the project.
public void AddWallet(string[] passSubset)
{
var arr = (GetOrCreateEntitlementDoc().root[WalletEntitlements.Key] = new PlistElementArray()) as PlistElementArray;
if ((passSubset == null || passSubset.Length == 0) && arr != null)
{
arr.values.Add(new PlistElementString(WalletEntitlements.BaseValue + WalletEntitlements.BaseValue));
}
else
{
for (var i = 0; i < passSubset.Length; i++)
{
if (arr != null)
arr.values.Add(new PlistElementString(WalletEntitlements.BaseValue + passSubset[i]));
}
}
project.AddCapability(m_TargetGuid, PBXCapabilityType.Wallet, m_EntitlementFilePath);
}
// Add Siri capability to the project.
public void AddSiri()
{
GetOrCreateEntitlementDoc().root[SiriEntitlements.Key] = new PlistElementBoolean(true);
project.AddCapability(m_TargetGuid, PBXCapabilityType.Siri, m_EntitlementFilePath);
}
// Add Apple Pay capability to the project.
public void AddApplePay(string[] merchants)
{
var arr = (GetOrCreateEntitlementDoc().root[ApplePayEntitlements.Key] = new PlistElementArray()) as PlistElementArray;
for (var i = 0; i < merchants.Length; i++)
{
arr.values.Add(new PlistElementString(merchants[i]));
}
project.AddCapability(m_TargetGuid, PBXCapabilityType.ApplePay, m_EntitlementFilePath);
}
// Add In App Purchase capability to the project.
public void AddInAppPurchase()
{
project.AddCapability(m_TargetGuid, PBXCapabilityType.InAppPurchase);
}
// Add Maps capability to the project.
public void AddMaps(MapsOptions options)
{
var bundleArr = (GetOrCreateInfoDoc().root[MapsInfo.BundleKey] ?? (GetOrCreateInfoDoc().root[MapsInfo.BundleKey] = new PlistElementArray())) as PlistElementArray;
bundleArr.values.Add(new PlistElementDict());
PlistElementDict bundleDic = GetOrCreateUniqueDictElementInArray(bundleArr);
bundleDic[MapsInfo.BundleNameKey] = new PlistElementString(MapsInfo.BundleNameValue);
var bundleTypeArr = (bundleDic[MapsInfo.BundleTypeKey] ?? (bundleDic[MapsInfo.BundleTypeKey] = new PlistElementArray())) as PlistElementArray;
GetOrCreateStringElementInArray(bundleTypeArr, MapsInfo.BundleTypeValue);
var optionArr = (GetOrCreateInfoDoc().root[MapsInfo.ModeKey] ??
(GetOrCreateInfoDoc().root[MapsInfo.ModeKey] = new PlistElementArray())) as PlistElementArray;
if ((options & MapsOptions.Airplane) == MapsOptions.Airplane)
{
GetOrCreateStringElementInArray(optionArr, MapsInfo.ModePlaneValue);
}
if ((options & MapsOptions.Bike) == MapsOptions.Bike)
{
GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeBikeValue);
}
if ((options & MapsOptions.Bus) == MapsOptions.Bus)
{
GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeBusValue);
}
if ((options & MapsOptions.Car) == MapsOptions.Car)
{
GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeCarValue);
}
if ((options & MapsOptions.Ferry) == MapsOptions.Ferry)
{
GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeFerryValue);
}
if ((options & MapsOptions.Other) == MapsOptions.Other)
{
GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeOtherValue);
}
if ((options & MapsOptions.Pedestrian) == MapsOptions.Pedestrian)
{
GetOrCreateStringElementInArray(optionArr, MapsInfo.ModePedestrianValue);
}
if ((options & MapsOptions.RideSharing) == MapsOptions.RideSharing)
{
GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeRideShareValue);
}
if ((options & MapsOptions.StreetCar) == MapsOptions.StreetCar)
{
GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeStreetCarValue);
}
if ((options & MapsOptions.Subway) == MapsOptions.Subway)
{
GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeSubwayValue);
}
if ((options & MapsOptions.Taxi) == MapsOptions.Taxi)
{
GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeTaxiValue);
}
if ((options & MapsOptions.Train) == MapsOptions.Train)
{
GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeTrainValue);
}
project.AddCapability(m_TargetGuid, PBXCapabilityType.Maps);
}
// Add Personal VPN capability to the project.
public void AddPersonalVPN()
{
var arr = (GetOrCreateEntitlementDoc().root[VPNEntitlements.Key] = new PlistElementArray()) as PlistElementArray;
arr.values.Add(new PlistElementString(VPNEntitlements.Value));
project.AddCapability(m_TargetGuid, PBXCapabilityType.PersonalVPN, m_EntitlementFilePath);
}
// Add Background capability to the project with the options wanted.
public void AddBackgroundModes(BackgroundModesOptions options)
{
var optionArr = (GetOrCreateInfoDoc().root[BackgroundInfo.Key] ??
(GetOrCreateInfoDoc().root[BackgroundInfo.Key] = new PlistElementArray())) as PlistElementArray;
if ((options & BackgroundModesOptions.ActsAsABluetoothLEAccessory) == BackgroundModesOptions.ActsAsABluetoothLEAccessory)
{
GetOrCreateStringElementInArray(optionArr, BackgroundInfo.ModeActsBluetoothValue);
}
if ((options & BackgroundModesOptions.AudioAirplayPiP) == BackgroundModesOptions.AudioAirplayPiP)
{
GetOrCreateStringElementInArray(optionArr, BackgroundInfo.ModeAudioValue);
}
if ((options & BackgroundModesOptions.BackgroundFetch) == BackgroundModesOptions.BackgroundFetch)
{
GetOrCreateStringElementInArray(optionArr, BackgroundInfo.ModeFetchValue);
}
if ((options & BackgroundModesOptions.ExternalAccessoryCommunication) == BackgroundModesOptions.ExternalAccessoryCommunication)
{
GetOrCreateStringElementInArray(optionArr, BackgroundInfo.ModeExtAccessoryValue);
}
if ((options & BackgroundModesOptions.LocationUpdates) == BackgroundModesOptions.LocationUpdates)
{
GetOrCreateStringElementInArray(optionArr, BackgroundInfo.ModeLocationValue);
}
if ((options & BackgroundModesOptions.NewsstandDownloads) == BackgroundModesOptions.NewsstandDownloads)
{
GetOrCreateStringElementInArray(optionArr, BackgroundInfo.ModeNewsstandValue);
}
if ((options & BackgroundModesOptions.RemoteNotifications) == BackgroundModesOptions.RemoteNotifications)
{
GetOrCreateStringElementInArray(optionArr, BackgroundInfo.ModePushValue);
}
if ((options & BackgroundModesOptions.VoiceOverIP) == BackgroundModesOptions.VoiceOverIP)
{
GetOrCreateStringElementInArray(optionArr, BackgroundInfo.ModeVOIPValue);
}
project.AddCapability(m_TargetGuid, PBXCapabilityType.BackgroundModes);
}
// Add Keychain Sharing capability to the project with a list of groups.
public void AddKeychainSharing(string[] accessGroups)
{
var arr = (GetOrCreateEntitlementDoc().root[KeyChainEntitlements.Key] = new PlistElementArray()) as PlistElementArray;
if (accessGroups != null)
{
for (var i = 0; i < accessGroups.Length; i++)
{
arr.values.Add(new PlistElementString(accessGroups[i]));
}
}
else
{
arr.values.Add(new PlistElementString(KeyChainEntitlements.DefaultValue));
}
project.AddCapability(m_TargetGuid, PBXCapabilityType.KeychainSharing, m_EntitlementFilePath);
}
// Add Inter App Audio capability to the project.
public void AddInterAppAudio()
{
GetOrCreateEntitlementDoc().root[AudioEntitlements.Key] = new PlistElementBoolean(true);
project.AddCapability(m_TargetGuid, PBXCapabilityType.InterAppAudio, m_EntitlementFilePath);
}
// Add Associated Domains capability to the project.
public void AddAssociatedDomains(string[] domains)
{
var arr = (GetOrCreateEntitlementDoc().root[AssociatedDomainsEntitlements.Key] = new PlistElementArray()) as PlistElementArray;
for (var i = 0; i < domains.Length; i++)
{
arr.values.Add(new PlistElementString(domains[i]));
}
project.AddCapability(m_TargetGuid, PBXCapabilityType.AssociatedDomains, m_EntitlementFilePath);
}
// Add App Groups capability to the project.
public void AddAppGroups(string[] groups)
{
var arr = (GetOrCreateEntitlementDoc().root[AppGroupsEntitlements.Key] = new PlistElementArray()) as PlistElementArray;
for (var i = 0; i < groups.Length; i++)
{
arr.values.Add(new PlistElementString(groups[i]));
}
project.AddCapability(m_TargetGuid, PBXCapabilityType.AppGroups, m_EntitlementFilePath);
}
// Add HomeKit capability to the project.
public void AddHomeKit()
{
GetOrCreateEntitlementDoc().root[HomeKitEntitlements.Key] = new PlistElementBoolean(true);
project.AddCapability(m_TargetGuid, PBXCapabilityType.HomeKit, m_EntitlementFilePath);
}
// Add Data Protection capability to the project.
public void AddDataProtection()
{
GetOrCreateEntitlementDoc().root[DataProtectionEntitlements.Key] = new PlistElementString(DataProtectionEntitlements.Value);
project.AddCapability(m_TargetGuid, PBXCapabilityType.DataProtection, m_EntitlementFilePath);
}
// Add HealthKit capability to the project.
public void AddHealthKit()
{
var capabilityArr = (GetOrCreateInfoDoc().root[HealthInfo.Key] ??
(GetOrCreateInfoDoc().root[HealthInfo.Key] = new PlistElementArray())) as PlistElementArray;
GetOrCreateStringElementInArray(capabilityArr, HealthInfo.Value);
GetOrCreateEntitlementDoc().root[HealthKitEntitlements.Key] = new PlistElementBoolean(true);
project.AddCapability(m_TargetGuid, PBXCapabilityType.HealthKit, m_EntitlementFilePath);
}
// Add Wireless Accessory Configuration capability to the project.
public void AddWirelessAccessoryConfiguration()
{
GetOrCreateEntitlementDoc().root[WirelessAccessoryConfigurationEntitlements.Key] = new PlistElementBoolean(true);
project.AddCapability(m_TargetGuid, PBXCapabilityType.WirelessAccessoryConfiguration, m_EntitlementFilePath);
}
private PlistDocument GetOrCreateEntitlementDoc()
{
if (m_Entitlements == null)
{
m_Entitlements = new PlistDocument();
string[] entitlementsFiles = Directory.GetFiles(m_BuildPath, m_EntitlementFilePath);
if (entitlementsFiles.Length > 0)
{
m_Entitlements.ReadFromFile(entitlementsFiles[0]);
}
else
{
m_Entitlements.Create();
}
}
return m_Entitlements;
}
private PlistDocument GetOrCreateInfoDoc()
{
if (m_InfoPlist == null)
{
m_InfoPlist = new PlistDocument();
string[] infoFiles = Directory.GetFiles(m_BuildPath + "/", "Info.plist");
if (infoFiles.Length > 0)
{
m_InfoPlist.ReadFromFile(infoFiles[0]);
}
else
{
m_InfoPlist.Create();
}
}
return m_InfoPlist;
}
private PlistElementString GetOrCreateStringElementInArray(PlistElementArray root, string value)
{
PlistElementString r = null;
var c = root.values.Count;
var exist = false;
for (var i = 0; i < c; i++)
{
if (root.values[i] is PlistElementString && (root.values[i] as PlistElementString).value == value)
{
r = root.values[i] as PlistElementString;
exist = true;
}
}
if (!exist)
{
r = new PlistElementString(value);
root.values.Add(r);
}
return r;
}
private PlistElementDict GetOrCreateUniqueDictElementInArray(PlistElementArray root)
{
PlistElementDict r;
if (root.values.Count == 0)
{
r = root.values[0] as PlistElementDict;
}
else
{
r = new PlistElementDict();
root.values.Add(r);
}
return r;
}
}
// The list of options available for Background Mode.
[Flags]
[Serializable]
public enum BackgroundModesOptions
{
None = 0,
AudioAirplayPiP = 1<<0,
LocationUpdates = 1<<1,
VoiceOverIP = 1<<2,
NewsstandDownloads = 1<<3,
ExternalAccessoryCommunication = 1<<4,
UsesBluetoothLEAccessory = 1<<5,
ActsAsABluetoothLEAccessory = 1<<6,
BackgroundFetch = 1<<7,
RemoteNotifications = 1<<8
}
// The list of options available for Maps.
[Serializable]
[Flags]
public enum MapsOptions
{
None = 0,
Airplane = 1<<0,
Bike = 1<<1,
Bus = 1<<2,
Car = 1<<3,
Ferry = 1<<4,
Pedestrian = 1<<5,
RideSharing = 1<<6,
StreetCar = 1<<7,
Subway = 1<<8,
Taxi = 1<<9,
Train = 1<<10,
Other = 1<<11
}
/* Follows the large quantity of string used as key and value all over the place in the info.plist or entitlements file. */
internal class GameCenterInfo
{
internal static readonly string Key = "UIRequiredDeviceCapabilities";
internal static readonly string Value = "gamekit";
}
internal class MapsInfo
{
internal static readonly string BundleKey = "CFBundleDocumentTypes";
internal static readonly string BundleNameKey = "CFBundleTypeName";
internal static readonly string BundleNameValue = "MKDirectionsRequest";
internal static readonly string BundleTypeKey = "LSItemContentTypes";
internal static readonly string BundleTypeValue = "com.apple.maps.directionsrequest";
internal static readonly string ModeKey = "MKDirectionsApplicationSupportedModes";
internal static readonly string ModePlaneValue = "MKDirectionsModePlane";
internal static readonly string ModeBikeValue = "MKDirectionsModeBike";
internal static readonly string ModeBusValue = "MKDirectionsModeBus";
internal static readonly string ModeCarValue = "MKDirectionsModeCar";
internal static readonly string ModeFerryValue = "MKDirectionsModeFerry";
internal static readonly string ModeOtherValue = "MKDirectionsModeOther";
internal static readonly string ModePedestrianValue = "MKDirectionsModePedestrian";
internal static readonly string ModeRideShareValue = "MKDirectionsModeRideShare";
internal static readonly string ModeStreetCarValue = "MKDirectionsModeStreetCar";
internal static readonly string ModeSubwayValue = "MKDirectionsModeSubway";
internal static readonly string ModeTaxiValue = "MKDirectionsModeTaxi";
internal static readonly string ModeTrainValue = "MKDirectionsModeTrain";
}
internal class BackgroundInfo
{
internal static readonly string Key = "UIBackgroundModes";
internal static readonly string ModeAudioValue = "audio";
internal static readonly string ModeBluetoothValue = "bluetooth-central";
internal static readonly string ModeActsBluetoothValue = "bluetooth-peripheral";
internal static readonly string ModeExtAccessoryValue = "external-accessory";
internal static readonly string ModeFetchValue = "fetch";
internal static readonly string ModeLocationValue = "location";
internal static readonly string ModeNewsstandValue = "newsstand-content";
internal static readonly string ModePushValue = "remote-notification";
internal static readonly string ModeVOIPValue = "voip";
}
internal class HealthInfo
{
internal static readonly string Key = "UIRequiredDeviceCapabilities";
internal static readonly string Value = "healthkit";
}
internal class ICloudEntitlements
{
internal static readonly string ContainerIdKey = "com.apple.developer.icloud-container-identifiers";
internal static readonly string UbiquityContainerIdKey = "com.apple.developer.ubiquity-container-identifiers";
internal static readonly string ContainerIdValue = "iCloud.$(CFBundleIdentifier)";
internal static readonly string UbiquityContainerIdValue = "iCloud.$(CFBundleIdentifier)";
internal static readonly string ServicesKey = "com.apple.developer.icloud-services";
internal static readonly string ServicesDocValue = "CloudDocuments";
internal static readonly string ServicesKitValue = "CloudKit";
internal static readonly string KeyValueStoreKey = "com.apple.developer.ubiquity-kvstore-identifier";
internal static readonly string KeyValueStoreValue = "$(TeamIdentifierPrefix)$(CFBundleIdentifier)";
}
internal class PushNotificationEntitlements
{
internal static readonly string Key = "aps-environment";
internal static readonly string DevelopmentValue = "development";
internal static readonly string ProductionValue = "production";
}
internal class WalletEntitlements
{
internal static readonly string Key = "com.apple.developer.pass-type-identifiers";
internal static readonly string BaseValue = "$(TeamIdentifierPrefix)";
internal static readonly string DefaultValue = "*";
}
internal class SiriEntitlements
{
internal static readonly string Key = "com.apple.developer.siri";
}
internal class ApplePayEntitlements
{
internal static readonly string Key = "com.apple.developer.in-app-payments";
}
internal class VPNEntitlements
{
internal static readonly string Key = "com.apple.developer.networking.vpn.api";
internal static readonly string Value = "allow-vpn";
}
internal class KeyChainEntitlements
{
internal static readonly string Key = "keychain-access-groups";
internal static readonly string DefaultValue = "$(AppIdentifierPrefix)$(CFBundleIdentifier)";
}
internal class AudioEntitlements
{
internal static readonly string Key = "inter-app-audio";
}
internal class AssociatedDomainsEntitlements
{
// value is an array of string of domains
internal static readonly string Key = "com.apple.developer.associated-domains";
}
internal class AppGroupsEntitlements
{
// value is an array of string of groups
internal static readonly string Key = "com.apple.security.application-groups";
}
internal class HomeKitEntitlements
{
// value is bool true.
internal static readonly string Key = "com.apple.developer.homekit";
}
internal class DataProtectionEntitlements
{
internal static readonly string Key = "com.apple.developer.default-data-protection";
internal static readonly string Value = "NSFileProtectionComplete";
}
internal class HealthKitEntitlements
{
// value is bool true.
internal static readonly string Key = "com.apple.developer.healthkit";
}
internal class WirelessAccessoryConfigurationEntitlements
{
// value is bool true.
internal static readonly string Key = "com.apple.external-accessory.wireless-configuration";
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 2bfeebf480ee141979c8981b78c0a488
timeCreated: 1496741691
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e076935cb7a13e942a62cc26cfd53401
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 00a558accb32e4d4c98b416ab890ed1b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,37 @@
fileFormatVersion: 2
guid: bb6999c8a5ce4ba99688ec579babe5b7
labels:
- gvh
- gvh_targets-editor
- gvh_version-1.2.135.0
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e35dd3967d7d19e4daab702656eb05dc
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f015a0243569fdd499d97c148a25456c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,212 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
SceneSettings:
m_ObjectHideFlags: 0
m_PVSData:
m_PVSObjectsArray: []
m_PVSPortalsArray: []
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: .25
backfaceThreshold: 100
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 6
m_Fog: 0
m_FogColor: {r: .5, g: .5, b: .5, a: 1}
m_FogMode: 3
m_FogDensity: .00999999978
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: .211999997, g: .226999998, b: .259000003, a: 1}
m_AmbientEquatorColor: {r: .114, g: .125, b: .133000001, a: 1}
m_AmbientGroundColor: {r: .0469999984, g: .0430000015, b: .0350000001, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: .5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
--- !u!157 &4
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 5
m_GIWorkflowMode: 0
m_LightmapsMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_TemporalCoherenceThreshold: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 1
m_LightmapEditorSettings:
serializedVersion: 3
m_Resolution: 2
m_BakeResolution: 40
m_TextureWidth: 1024
m_TextureHeight: 1024
m_AOMaxDistance: 1
m_Padding: 2
m_CompAOExponent: 0
m_LightmapParameters: {fileID: 0}
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherRayCount: 1024
m_ReflectionCompression: 2
m_LightmapSnapshot: {fileID: 0}
m_RuntimeCPUUsage: 25
--- !u!196 &5
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentRadius: .5
agentHeight: 2
agentSlope: 45
agentClimb: .400000006
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
accuratePlacement: 0
minRegionArea: 2
cellSize: .166666672
manualCellSize: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &17281797
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
m_Component:
- 4: {fileID: 17281802}
- 20: {fileID: 17281801}
- 92: {fileID: 17281800}
- 124: {fileID: 17281799}
- 81: {fileID: 17281798}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &17281798
AudioListener:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
--- !u!124 &17281799
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
--- !u!92 &17281800
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
--- !u!20 &17281801
Camera:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 2
m_BackGroundColor: {r: .23137255, g: .349019617, b: .596078455, a: 1}
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: .300000012
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: .0219999999
m_StereoMirrorMode: 0
--- !u!4 &17281802
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
--- !u!1 &1482271768
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
m_Component:
- 4: {fileID: 1482271770}
- 114: {fileID: 1482271769}
m_Layer: 0
m_Name: AccessTokenMenu
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1482271769
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1482271768}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4cc408e158eec46b28b93a44fc8819ff, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!4 &1482271770
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1482271768}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -6.42004156, y: -8.74592876, z: -1.64325905}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 67cb5b2387b8e4ec9b2fa69ad9510e9b
timeCreated: 1447720184
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+212
View File
@@ -0,0 +1,212 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
SceneSettings:
m_ObjectHideFlags: 0
m_PVSData:
m_PVSObjectsArray: []
m_PVSPortalsArray: []
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: .25
backfaceThreshold: 100
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 6
m_Fog: 0
m_FogColor: {r: .5, g: .5, b: .5, a: 1}
m_FogMode: 3
m_FogDensity: .00999999978
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: .211999997, g: .226999998, b: .259000003, a: 1}
m_AmbientEquatorColor: {r: .114, g: .125, b: .133000001, a: 1}
m_AmbientGroundColor: {r: .0469999984, g: .0430000015, b: .0350000001, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: .5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
--- !u!157 &4
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 5
m_GIWorkflowMode: 0
m_LightmapsMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_TemporalCoherenceThreshold: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 1
m_LightmapEditorSettings:
serializedVersion: 3
m_Resolution: 2
m_BakeResolution: 40
m_TextureWidth: 1024
m_TextureHeight: 1024
m_AOMaxDistance: 1
m_Padding: 2
m_CompAOExponent: 0
m_LightmapParameters: {fileID: 0}
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherRayCount: 1024
m_ReflectionCompression: 2
m_LightmapSnapshot: {fileID: 0}
m_RuntimeCPUUsage: 25
--- !u!196 &5
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentRadius: .5
agentHeight: 2
agentSlope: 45
agentClimb: .400000006
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
accuratePlacement: 0
minRegionArea: 2
cellSize: .166666672
manualCellSize: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &17281797
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
m_Component:
- 4: {fileID: 17281802}
- 20: {fileID: 17281801}
- 92: {fileID: 17281800}
- 124: {fileID: 17281799}
- 81: {fileID: 17281798}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &17281798
AudioListener:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
--- !u!124 &17281799
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
--- !u!92 &17281800
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
--- !u!20 &17281801
Camera:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 2
m_BackGroundColor: {r: .23137255, g: .349019617, b: .596078455, a: 1}
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: .300000012
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: .0219999999
m_StereoMirrorMode: 0
--- !u!4 &17281802
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
--- !u!1 &1482271768
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
m_Component:
- 4: {fileID: 1482271770}
- 114: {fileID: 1482271769}
m_Layer: 0
m_Name: AppEvents
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1482271769
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1482271768}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e3c0dd81ff77c4c30834810815c69f6d, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!4 &1482271770
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1482271768}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -6.42004156, y: -8.74592876, z: -1.64325905}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 68ab940fa15e34433bff18301686b080
timeCreated: 1434663633
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+212
View File
@@ -0,0 +1,212 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
SceneSettings:
m_ObjectHideFlags: 0
m_PVSData:
m_PVSObjectsArray: []
m_PVSPortalsArray: []
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: .25
backfaceThreshold: 100
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 6
m_Fog: 0
m_FogColor: {r: .5, g: .5, b: .5, a: 1}
m_FogMode: 3
m_FogDensity: .00999999978
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: .211999997, g: .226999998, b: .259000003, a: 1}
m_AmbientEquatorColor: {r: .114, g: .125, b: .133000001, a: 1}
m_AmbientGroundColor: {r: .0469999984, g: .0430000015, b: .0350000001, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: .5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
--- !u!157 &4
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 5
m_GIWorkflowMode: 0
m_LightmapsMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_TemporalCoherenceThreshold: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 1
m_LightmapEditorSettings:
serializedVersion: 3
m_Resolution: 2
m_BakeResolution: 40
m_TextureWidth: 1024
m_TextureHeight: 1024
m_AOMaxDistance: 1
m_Padding: 2
m_CompAOExponent: 0
m_LightmapParameters: {fileID: 0}
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherRayCount: 1024
m_ReflectionCompression: 2
m_LightmapSnapshot: {fileID: 0}
m_RuntimeCPUUsage: 25
--- !u!196 &5
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentRadius: .5
agentHeight: 2
agentSlope: 45
agentClimb: .400000006
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
accuratePlacement: 0
minRegionArea: 2
cellSize: .166666672
manualCellSize: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &17281797
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
m_Component:
- 4: {fileID: 17281802}
- 20: {fileID: 17281801}
- 92: {fileID: 17281800}
- 124: {fileID: 17281799}
- 81: {fileID: 17281798}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &17281798
AudioListener:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
--- !u!124 &17281799
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
--- !u!92 &17281800
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
--- !u!20 &17281801
Camera:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 2
m_BackGroundColor: {r: .23137255, g: .349019617, b: .596078455, a: 1}
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: .300000012
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: .0219999999
m_StereoMirrorMode: 0
--- !u!4 &17281802
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
--- !u!1 &1482271768
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
m_Component:
- 4: {fileID: 1482271770}
- 114: {fileID: 1482271769}
m_Layer: 0
m_Name: AppLinks
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1482271769
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1482271768}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f9f0b7257fa054227be6e26bf1f6b339, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!4 &1482271770
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1482271768}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -6.42004156, y: -8.74592876, z: -1.64325905}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4ac12dfde6570493291366d0ab3eb20d
timeCreated: 1434663633
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,212 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
SceneSettings:
m_ObjectHideFlags: 0
m_PVSData:
m_PVSObjectsArray: []
m_PVSPortalsArray: []
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: .25
backfaceThreshold: 100
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 6
m_Fog: 0
m_FogColor: {r: .5, g: .5, b: .5, a: 1}
m_FogMode: 3
m_FogDensity: .00999999978
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: .211999997, g: .226999998, b: .259000003, a: 1}
m_AmbientEquatorColor: {r: .114, g: .125, b: .133000001, a: 1}
m_AmbientGroundColor: {r: .0469999984, g: .0430000015, b: .0350000001, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: .5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
--- !u!157 &4
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 5
m_GIWorkflowMode: 0
m_LightmapsMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_TemporalCoherenceThreshold: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 1
m_LightmapEditorSettings:
serializedVersion: 3
m_Resolution: 2
m_BakeResolution: 40
m_TextureWidth: 1024
m_TextureHeight: 1024
m_AOMaxDistance: 1
m_Padding: 2
m_CompAOExponent: 0
m_LightmapParameters: {fileID: 0}
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherRayCount: 1024
m_ReflectionCompression: 2
m_LightmapSnapshot: {fileID: 0}
m_RuntimeCPUUsage: 25
--- !u!196 &5
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentRadius: .5
agentHeight: 2
agentSlope: 45
agentClimb: .400000006
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
accuratePlacement: 0
minRegionArea: 2
cellSize: .166666672
manualCellSize: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &17281797
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
m_Component:
- 4: {fileID: 17281802}
- 20: {fileID: 17281801}
- 92: {fileID: 17281800}
- 124: {fileID: 17281799}
- 81: {fileID: 17281798}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &17281798
AudioListener:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
--- !u!124 &17281799
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
--- !u!92 &17281800
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
--- !u!20 &17281801
Camera:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 2
m_BackGroundColor: {r: .23137255, g: .349019617, b: .596078455, a: 1}
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: .300000012
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: .0219999999
m_StereoMirrorMode: 0
--- !u!4 &17281802
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
--- !u!1 &1482271768
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
m_Component:
- 4: {fileID: 1482271770}
- 114: {fileID: 1482271769}
m_Layer: 0
m_Name: AppRequests
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1482271769
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1482271768}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3b4c675f81a254b87adc8ad01006c580, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!4 &1482271770
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1482271768}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -6.42004156, y: -8.74592876, z: -1.64325905}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c2250c9c5cf00425384401321f8dffb4
timeCreated: 1434135388
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,212 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
SceneSettings:
m_ObjectHideFlags: 0
m_PVSData:
m_PVSObjectsArray: []
m_PVSPortalsArray: []
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: .25
backfaceThreshold: 100
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 6
m_Fog: 0
m_FogColor: {r: .5, g: .5, b: .5, a: 1}
m_FogMode: 3
m_FogDensity: .00999999978
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: .211999997, g: .226999998, b: .259000003, a: 1}
m_AmbientEquatorColor: {r: .114, g: .125, b: .133000001, a: 1}
m_AmbientGroundColor: {r: .0469999984, g: .0430000015, b: .0350000001, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: .5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
--- !u!157 &4
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 5
m_GIWorkflowMode: 0
m_LightmapsMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_TemporalCoherenceThreshold: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 1
m_LightmapEditorSettings:
serializedVersion: 3
m_Resolution: 2
m_BakeResolution: 40
m_TextureWidth: 1024
m_TextureHeight: 1024
m_AOMaxDistance: 1
m_Padding: 2
m_CompAOExponent: 0
m_LightmapParameters: {fileID: 0}
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherRayCount: 1024
m_ReflectionCompression: 2
m_LightmapSnapshot: {fileID: 0}
m_RuntimeCPUUsage: 25
--- !u!196 &5
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentRadius: .5
agentHeight: 2
agentSlope: 45
agentClimb: .400000006
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
accuratePlacement: 0
minRegionArea: 2
cellSize: .166666672
manualCellSize: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &17281797
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
m_Component:
- 4: {fileID: 17281802}
- 20: {fileID: 17281801}
- 92: {fileID: 17281800}
- 124: {fileID: 17281799}
- 81: {fileID: 17281798}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &17281798
AudioListener:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
--- !u!124 &17281799
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
--- !u!92 &17281800
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
--- !u!20 &17281801
Camera:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 2
m_BackGroundColor: {r: .23137255, g: .349019617, b: .596078455, a: 1}
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: .300000012
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: .0219999999
m_StereoMirrorMode: 0
--- !u!4 &17281802
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
--- !u!1 &1482271768
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
m_Component:
- 4: {fileID: 1482271770}
- 114: {fileID: 1482271769}
m_Layer: 0
m_Name: DialogShare
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1482271769
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1482271768}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e93c4155902d3496399630ee494eab6b, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!4 &1482271770
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1482271768}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -6.42004156, y: -8.74592876, z: -1.64325905}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 190c345841ecc464e9a122f04369757e
timeCreated: 1434132966
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,212 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
SceneSettings:
m_ObjectHideFlags: 0
m_PVSData:
m_PVSObjectsArray: []
m_PVSPortalsArray: []
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: .25
backfaceThreshold: 100
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 6
m_Fog: 0
m_FogColor: {r: .5, g: .5, b: .5, a: 1}
m_FogMode: 3
m_FogDensity: .00999999978
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: .211999997, g: .226999998, b: .259000003, a: 1}
m_AmbientEquatorColor: {r: .114, g: .125, b: .133000001, a: 1}
m_AmbientGroundColor: {r: .0469999984, g: .0430000015, b: .0350000001, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: .5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
--- !u!157 &4
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 5
m_GIWorkflowMode: 0
m_LightmapsMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_TemporalCoherenceThreshold: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 1
m_LightmapEditorSettings:
serializedVersion: 3
m_Resolution: 2
m_BakeResolution: 40
m_TextureWidth: 1024
m_TextureHeight: 1024
m_AOMaxDistance: 1
m_Padding: 2
m_CompAOExponent: 0
m_LightmapParameters: {fileID: 0}
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherRayCount: 1024
m_ReflectionCompression: 2
m_LightmapSnapshot: {fileID: 0}
m_RuntimeCPUUsage: 25
--- !u!196 &5
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentRadius: .5
agentHeight: 2
agentSlope: 45
agentClimb: .400000006
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
accuratePlacement: 0
minRegionArea: 2
cellSize: .166666672
manualCellSize: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &17281797
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
m_Component:
- 4: {fileID: 17281802}
- 20: {fileID: 17281801}
- 92: {fileID: 17281800}
- 124: {fileID: 17281799}
- 81: {fileID: 17281798}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &17281798
AudioListener:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
--- !u!124 &17281799
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
--- !u!92 &17281800
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
--- !u!20 &17281801
Camera:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 2
m_BackGroundColor: {r: .23137255, g: .349019617, b: .596078455, a: 1}
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: .300000012
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: .0219999999
m_StereoMirrorMode: 0
--- !u!4 &17281802
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
--- !u!1 &1482271768
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
m_Component:
- 4: {fileID: 1482271770}
- 114: {fileID: 1482271769}
m_Layer: 0
m_Name: GraphRequest
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1482271769
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1482271768}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 23c3cb06c2209474e9a8441e2712d5d2, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!4 &1482271770
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1482271768}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -6.42004156, y: -8.74592876, z: -1.64325905}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 444ae7ddf432b457a97bfe42021075e3
timeCreated: 1434488369
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+212
View File
@@ -0,0 +1,212 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
SceneSettings:
m_ObjectHideFlags: 0
m_PVSData:
m_PVSObjectsArray: []
m_PVSPortalsArray: []
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: .25
backfaceThreshold: 100
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 6
m_Fog: 0
m_FogColor: {r: .5, g: .5, b: .5, a: 1}
m_FogMode: 3
m_FogDensity: .00999999978
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: .211999997, g: .226999998, b: .259000003, a: 1}
m_AmbientEquatorColor: {r: .114, g: .125, b: .133000001, a: 1}
m_AmbientGroundColor: {r: .0469999984, g: .0430000015, b: .0350000001, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: .5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
--- !u!157 &4
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 5
m_GIWorkflowMode: 0
m_LightmapsMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_TemporalCoherenceThreshold: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 1
m_LightmapEditorSettings:
serializedVersion: 3
m_Resolution: 2
m_BakeResolution: 40
m_TextureWidth: 1024
m_TextureHeight: 1024
m_AOMaxDistance: 1
m_Padding: 2
m_CompAOExponent: 0
m_LightmapParameters: {fileID: 0}
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherRayCount: 1024
m_ReflectionCompression: 2
m_LightmapSnapshot: {fileID: 0}
m_RuntimeCPUUsage: 25
--- !u!196 &5
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentRadius: .5
agentHeight: 2
agentSlope: 45
agentClimb: .400000006
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
accuratePlacement: 0
minRegionArea: 2
cellSize: .166666672
manualCellSize: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &17281797
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
m_Component:
- 4: {fileID: 17281802}
- 20: {fileID: 17281801}
- 92: {fileID: 17281800}
- 124: {fileID: 17281799}
- 81: {fileID: 17281798}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &17281798
AudioListener:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
--- !u!124 &17281799
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
--- !u!92 &17281800
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
--- !u!20 &17281801
Camera:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 2
m_BackGroundColor: {r: .23137255, g: .349019617, b: .596078455, a: 1}
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: .300000012
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: .0219999999
m_StereoMirrorMode: 0
--- !u!4 &17281802
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 17281797}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
--- !u!1 &1482271768
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
m_Component:
- 4: {fileID: 1482271770}
- 114: {fileID: 1482271769}
m_Layer: 0
m_Name: LogView
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1482271769
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1482271768}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 910cbe16250cb4363b70464c39fc701a, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!4 &1482271770
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1482271768}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -6.42004156, y: -8.74592876, z: -1.64325905}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c07ff0bf6bea74c2eb681ac0cae44265
timeCreated: 1434143106
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+212
View File
@@ -0,0 +1,212 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
SceneSettings:
m_ObjectHideFlags: 0
m_PVSData:
m_PVSObjectsArray: []
m_PVSPortalsArray: []
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: .25
backfaceThreshold: 100
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 6
m_Fog: 0
m_FogColor: {r: .5, g: .5, b: .5, a: 1}
m_FogMode: 3
m_FogDensity: .00999999978
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: .200000003, g: .200000003, b: .200000003, a: 1}
m_AmbientEquatorColor: {r: .200000003, g: .200000003, b: .200000003, a: 1}
m_AmbientGroundColor: {r: .200000003, g: .200000003, b: .200000003, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 3
m_SkyboxMaterial: {fileID: 0}
m_HaloStrength: .5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
--- !u!157 &4
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 5
m_GIWorkflowMode: 1
m_LightmapsMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_TemporalCoherenceThreshold: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 3
m_Resolution: 1
m_BakeResolution: 50
m_TextureWidth: 1024
m_TextureHeight: 1024
m_AOMaxDistance: 1
m_Padding: 2
m_CompAOExponent: 0
m_LightmapParameters: {fileID: 0}
m_TextureCompression: 0
m_FinalGather: 0
m_FinalGatherRayCount: 1024
m_ReflectionCompression: 2
m_LightmapSnapshot: {fileID: 0}
m_RuntimeCPUUsage: 25
--- !u!196 &5
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentRadius: .5
agentHeight: 2
agentSlope: 45
agentClimb: .400000006
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
accuratePlacement: 0
minRegionArea: 2
cellSize: .166666657
manualCellSize: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &787078726
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
m_Component:
- 4: {fileID: 787078731}
- 20: {fileID: 787078730}
- 92: {fileID: 787078729}
- 124: {fileID: 787078728}
- 81: {fileID: 787078727}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &787078727
AudioListener:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 787078726}
m_Enabled: 1
--- !u!124 &787078728
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 787078726}
m_Enabled: 1
--- !u!92 &787078729
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 787078726}
m_Enabled: 1
--- !u!20 &787078730
Camera:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 787078726}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: .23137255, g: .349019617, b: .596078455, a: 1}
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: .300000012
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 100
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: .0219999999
m_StereoMirrorMode: 0
--- !u!4 &787078731
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 787078726}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
--- !u!1 &1988862590
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
m_Component:
- 4: {fileID: 1988862591}
- 114: {fileID: 1988862593}
m_Layer: 0
m_Name: MainMenu
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1988862591
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1988862590}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -6.42004156, y: -8.74592876, z: -1.64325905}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
--- !u!114 &1988862593
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1988862590}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 922e3ad8d88a146b3b392cd8c84edd6a, type: 3}
m_Name:
m_EditorClassIdentifier:
@@ -0,0 +1,6 @@
fileFormatVersion: 2
guid: 7c38a8c9adc9d5c4b869612e4033ead8
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+212
View File
@@ -0,0 +1,212 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
SceneSettings:
m_ObjectHideFlags: 0
m_PVSData:
m_PVSObjectsArray: []
m_PVSPortalsArray: []
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: .25
backfaceThreshold: 100
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 6
m_Fog: 0
m_FogColor: {r: .5, g: .5, b: .5, a: 1}
m_FogMode: 3
m_FogDensity: .00999999978
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: .200000003, g: .200000003, b: .200000003, a: 1}
m_AmbientEquatorColor: {r: .200000003, g: .200000003, b: .200000003, a: 1}
m_AmbientGroundColor: {r: .200000003, g: .200000003, b: .200000003, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 3
m_SkyboxMaterial: {fileID: 0}
m_HaloStrength: .5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
--- !u!157 &4
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 5
m_GIWorkflowMode: 1
m_LightmapsMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_TemporalCoherenceThreshold: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 3
m_Resolution: 1
m_BakeResolution: 50
m_TextureWidth: 1024
m_TextureHeight: 1024
m_AOMaxDistance: 1
m_Padding: 2
m_CompAOExponent: 0
m_LightmapParameters: {fileID: 0}
m_TextureCompression: 0
m_FinalGather: 0
m_FinalGatherRayCount: 1024
m_ReflectionCompression: 2
m_LightmapSnapshot: {fileID: 0}
m_RuntimeCPUUsage: 25
--- !u!196 &5
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentRadius: .5
agentHeight: 2
agentSlope: 45
agentClimb: .400000006
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
accuratePlacement: 0
minRegionArea: 2
cellSize: .166666657
manualCellSize: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &787078726
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
m_Component:
- 4: {fileID: 787078731}
- 20: {fileID: 787078730}
- 92: {fileID: 787078729}
- 124: {fileID: 787078728}
- 81: {fileID: 787078727}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &787078727
AudioListener:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 787078726}
m_Enabled: 1
--- !u!124 &787078728
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 787078726}
m_Enabled: 1
--- !u!92 &787078729
Behaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 787078726}
m_Enabled: 1
--- !u!20 &787078730
Camera:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 787078726}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: .23137255, g: .349019617, b: .596078455, a: 1}
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: .300000012
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 100
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: .0219999999
m_StereoMirrorMode: 0
--- !u!4 &787078731
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 787078726}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
--- !u!1 &1988862590
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 4
m_Component:
- 4: {fileID: 1988862591}
- 114: {fileID: 1988862593}
m_Layer: 0
m_Name: Pay
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1988862591
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1988862590}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -6.42004156, y: -8.74592876, z: -1.64325905}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
--- !u!114 &1988862593
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1988862590}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7f08c9721703046ec883e57562184726, type: 3}
m_Name:
m_EditorClassIdentifier:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3ee189cdb21ea4bdb9d7022a0780c44c
timeCreated: 1441927990
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 69127c4c57aff0a4ebdbc24c5fd306ea
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,263 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
* copy, modify, and distribute this software in source code or binary form for use
* in connection with the web services and APIs provided by Facebook.
*
* As with any software that integrates with the Facebook platform, your use of
* this software is subject to the Facebook Developer Principles and Policies
* [http://developers.facebook.com/policy/]. This copyright notice shall be
* included in all copies or substantial portions of the software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Facebook.Unity.Example
{
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
internal class ConsoleBase : MonoBehaviour
{
private const int DpiScalingFactor = 160;
private static Stack<string> menuStack = new Stack<string>();
private string status = "Ready";
private string lastResponse = string.Empty;
private Vector2 scrollPosition = Vector2.zero;
// DPI scaling
private float? scaleFactor;
private GUIStyle textStyle;
private GUIStyle buttonStyle;
private GUIStyle textInputStyle;
private GUIStyle labelStyle;
protected static int ButtonHeight
{
get
{
return Constants.IsMobile ? 60 : 24;
}
}
protected static int MainWindowWidth
{
get
{
return Constants.IsMobile ? Screen.width - 30 : 700;
}
}
protected static int MainWindowFullWidth
{
get
{
return Constants.IsMobile ? Screen.width : 760;
}
}
protected static int MarginFix
{
get
{
return Constants.IsMobile ? 0 : 48;
}
}
protected static Stack<string> MenuStack
{
get
{
return ConsoleBase.menuStack;
}
set
{
ConsoleBase.menuStack = value;
}
}
protected string Status
{
get
{
return this.status;
}
set
{
this.status = value;
}
}
protected Texture2D LastResponseTexture { get; set; }
protected string LastResponse
{
get
{
return this.lastResponse;
}
set
{
this.lastResponse = value;
}
}
protected Vector2 ScrollPosition
{
get
{
return this.scrollPosition;
}
set
{
this.scrollPosition = value;
}
}
// Note we assume that these styles will be accessed from OnGUI otherwise the
// unity APIs will fail.
protected float ScaleFactor
{
get
{
if (!this.scaleFactor.HasValue)
{
this.scaleFactor = Screen.dpi / ConsoleBase.DpiScalingFactor;
}
return this.scaleFactor.Value;
}
}
protected int FontSize
{
get
{
return (int)Math.Round(this.ScaleFactor * 16);
}
}
protected GUIStyle TextStyle
{
get
{
if (this.textStyle == null)
{
this.textStyle = new GUIStyle(GUI.skin.textArea);
this.textStyle.alignment = TextAnchor.UpperLeft;
this.textStyle.wordWrap = true;
this.textStyle.padding = new RectOffset(10, 10, 10, 10);
this.textStyle.stretchHeight = true;
this.textStyle.stretchWidth = false;
this.textStyle.fontSize = this.FontSize;
}
return this.textStyle;
}
}
protected GUIStyle ButtonStyle
{
get
{
if (this.buttonStyle == null)
{
this.buttonStyle = new GUIStyle(GUI.skin.button);
this.buttonStyle.fontSize = this.FontSize;
}
return this.buttonStyle;
}
}
protected GUIStyle TextInputStyle
{
get
{
if (this.textInputStyle == null)
{
this.textInputStyle = new GUIStyle(GUI.skin.textField);
this.textInputStyle.fontSize = this.FontSize;
}
return this.textInputStyle;
}
}
protected GUIStyle LabelStyle
{
get
{
if (this.labelStyle == null)
{
this.labelStyle = new GUIStyle(GUI.skin.label);
this.labelStyle.fontSize = this.FontSize;
}
return this.labelStyle;
}
}
protected virtual void Awake()
{
// Limit the framerate to 60 to keep device from burning through cpu
Application.targetFrameRate = 60;
}
protected bool Button(string label)
{
return GUILayout.Button(
label,
this.ButtonStyle,
GUILayout.MinHeight(ConsoleBase.ButtonHeight * this.ScaleFactor),
GUILayout.MaxWidth(ConsoleBase.MainWindowWidth));
}
protected void LabelAndTextField(string label, ref string text)
{
GUILayout.BeginHorizontal();
GUILayout.Label(label, this.LabelStyle, GUILayout.MaxWidth(200 * this.ScaleFactor));
text = GUILayout.TextField(
text,
this.TextInputStyle,
GUILayout.MaxWidth(ConsoleBase.MainWindowWidth - 150));
GUILayout.EndHorizontal();
}
protected bool IsHorizontalLayout()
{
#if UNITY_IOS || UNITY_ANDROID
return Screen.orientation == ScreenOrientation.Landscape;
#else
return true;
#endif
}
protected void SwitchMenu(Type menuClass)
{
ConsoleBase.menuStack.Push(this.GetType().Name);
SceneManager.LoadScene(menuClass.Name);
}
protected void GoBack()
{
if (ConsoleBase.menuStack.Any())
{
SceneManager.LoadScene(ConsoleBase.menuStack.Pop());
}
}
}
}
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: e8659f5605d094c19a8b7ef9471c3603
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,71 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
* copy, modify, and distribute this software in source code or binary form for use
* in connection with the web services and APIs provided by Facebook.
*
* As with any software that integrates with the Facebook platform, your use of
* this software is subject to the Facebook Developer Principles and Policies
* [http://developers.facebook.com/policy/]. This copyright notice shall be
* included in all copies or substantial portions of the software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Facebook.Unity.Example
{
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
internal class LogView : ConsoleBase
{
private static string datePatt = @"M/d/yyyy hh:mm:ss tt";
private static IList<string> events = new List<string>();
public static void AddLog(string log)
{
events.Insert(0, string.Format("{0}\n{1}\n", DateTime.Now.ToString(datePatt), log));
}
protected void OnGUI()
{
GUILayout.BeginVertical();
//GUILayout.Space(Screen.safeArea.yMin + 10);
if (this.Button("Back"))
{
this.GoBack();
}
#if UNITY_IOS || UNITY_ANDROID || UNITY_WP8
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved)
{
Vector2 scrollPosition = this.ScrollPosition;
scrollPosition.y += Input.GetTouch(0).deltaPosition.y;
this.ScrollPosition = scrollPosition;
}
#endif
this.ScrollPosition = GUILayout.BeginScrollView(
this.ScrollPosition,
GUILayout.MinWidth(ConsoleBase.MainWindowFullWidth));
GUILayout.TextArea(
string.Join("\n", events.ToArray()),
this.TextStyle,
GUILayout.ExpandHeight(true),
GUILayout.MaxWidth(ConsoleBase.MainWindowWidth));
GUILayout.EndScrollView();
GUILayout.EndVertical();
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 910cbe16250cb4363b70464c39fc701a
timeCreated: 1434143113
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,232 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
* copy, modify, and distribute this software in source code or binary form for use
* in connection with the web services and APIs provided by Facebook.
*
* As with any software that integrates with the Facebook platform, your use of
* this software is subject to the Facebook Developer Principles and Policies
* [http://developers.facebook.com/policy/]. This copyright notice shall be
* included in all copies or substantial portions of the software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Facebook.Unity.Example
{
using System;
using System.Linq;
using UnityEngine;
internal abstract class MenuBase : ConsoleBase
{
private static ShareDialogMode shareDialogMode;
protected abstract void GetGui();
protected virtual bool ShowDialogModeSelector()
{
return false;
}
protected virtual bool ShowBackButton()
{
return true;
}
protected void HandleResult(IResult result)
{
if (result == null)
{
this.LastResponse = "Null Response\n";
LogView.AddLog(this.LastResponse);
return;
}
this.LastResponseTexture = null;
// Some platforms return the empty string instead of null.
if (!string.IsNullOrEmpty(result.Error))
{
this.Status = "Error - Check log for details";
this.LastResponse = "Error Response:\n" + result.Error;
}
else if (result.Cancelled)
{
this.Status = "Cancelled - Check log for details";
this.LastResponse = "Cancelled Response:\n" + result.RawResult;
}
else if (!string.IsNullOrEmpty(result.RawResult))
{
this.Status = "Success - Check log for details";
this.LastResponse = "Success Response:\n" + result.RawResult;
}
else
{
this.LastResponse = "Empty Response\n";
}
LogView.AddLog(result.ToString());
}
protected void HandleLimitedLoginResult(IResult result)
{
if (result == null)
{
this.LastResponse = "Null Response\n";
LogView.AddLog(this.LastResponse);
return;
}
this.LastResponseTexture = null;
// Some platforms return the empty string instead of null.
if (!string.IsNullOrEmpty(result.Error))
{
this.Status = "Error - Check log for details";
this.LastResponse = "Error Response:\n" + result.Error;
}
else if (result.Cancelled)
{
this.Status = "Cancelled - Check log for details";
this.LastResponse = "Cancelled Response:\n" + result.RawResult;
}
else if (!string.IsNullOrEmpty(result.RawResult))
{
this.Status = "Success - Check log for details";
this.LastResponse = "Success Response:\n" + result.RawResult;
}
else
{
this.LastResponse = "Empty Response\n";
}
String resultSummary = "Limited login results\n\n";
var profile = FB.Mobile.CurrentProfile();
resultSummary += "name: " + profile.Name + "\n";
resultSummary += "id: " + profile.UserID + "\n";
resultSummary += "email: " + profile.Email + "\n";
resultSummary += "pic URL: " + profile.ImageURL + "\n";
resultSummary += "birthday: " + profile.Birthday + "\n";
resultSummary += "age range: " + profile.AgeRange + "\n";
resultSummary += "first name: " + profile.FirstName + "\n";
resultSummary += "middle name: " + profile.MiddleName + "\n";
resultSummary += "last name: " + profile.LastName + "\n";
resultSummary += "friends: " + String.Join(",", profile.FriendIDs) + "\n";
resultSummary += "hometown: " + profile.Hometown?.Name + "\n";
resultSummary += "location: " + profile.Location?.Name + "\n";
resultSummary += "gender: " + profile.Gender + "\n";
LogView.AddLog(resultSummary);
}
protected void OnGUI()
{
if (this.IsHorizontalLayout())
{
GUILayout.BeginHorizontal();
GUILayout.BeginVertical();
}
//GUILayout.Space(Screen.safeArea.yMin + 10);
GUILayout.Label(this.GetType().Name, this.LabelStyle);
this.AddStatus();
#if UNITY_IOS || UNITY_ANDROID || UNITY_WP8
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved)
{
Vector2 scrollPosition = this.ScrollPosition;
scrollPosition.y += Input.GetTouch(0).deltaPosition.y;
this.ScrollPosition = scrollPosition;
}
#endif
this.ScrollPosition = GUILayout.BeginScrollView(
this.ScrollPosition,
GUILayout.MinWidth(ConsoleBase.MainWindowFullWidth));
GUILayout.BeginHorizontal();
if (this.ShowBackButton())
{
this.AddBackButton();
}
this.AddLogButton();
if (this.ShowBackButton())
{
// Fix GUILayout margin issues
GUILayout.Label(GUIContent.none, GUILayout.MinWidth(ConsoleBase.MarginFix));
}
GUILayout.EndHorizontal();
if (this.ShowDialogModeSelector())
{
this.AddDialogModeButtons();
}
GUILayout.BeginVertical();
// Add the ui from decendants
this.GetGui();
GUILayout.Space(10);
GUILayout.EndVertical();
GUILayout.EndScrollView();
}
private void AddStatus()
{
GUILayout.Space(5);
GUILayout.Box("Status: " + this.Status, this.TextStyle, GUILayout.MinWidth(ConsoleBase.MainWindowWidth));
}
private void AddBackButton()
{
GUI.enabled = ConsoleBase.MenuStack.Any();
if (this.Button("Back"))
{
this.GoBack();
}
GUI.enabled = true;
}
private void AddLogButton()
{
if (this.Button("Log"))
{
this.SwitchMenu(typeof(LogView));
}
}
private void AddDialogModeButtons()
{
GUILayout.BeginHorizontal();
foreach (var value in Enum.GetValues(typeof(ShareDialogMode)))
{
this.AddDialogModeButton((ShareDialogMode)value);
}
GUILayout.EndHorizontal();
}
private void AddDialogModeButton(ShareDialogMode mode)
{
bool enabled = GUI.enabled;
GUI.enabled = enabled && (mode != shareDialogMode);
if (this.Button(mode.ToString()))
{
shareDialogMode = mode;
FB.Mobile.ShareDialogMode = mode;
}
GUI.enabled = enabled;
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 8f28f9112a7d44d3c999fbd95333abbb
timeCreated: 1465553943
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f187a1fd548e2a049a6cfef1dcef73e6
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,33 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
* copy, modify, and distribute this software in source code or binary form for use
* in connection with the web services and APIs provided by Facebook.
*
* As with any software that integrates with the Facebook platform, your use of
* this software is subject to the Facebook Developer Principles and Policies
* [http://developers.facebook.com/policy/]. This copyright notice shall be
* included in all copies or substantial portions of the software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Facebook.Unity.Example
{
internal class AccessTokenMenu : MenuBase
{
protected override void GetGui()
{
if (this.Button("Refresh Access Token"))
{
FB.Mobile.RefreshCurrentAccessToken(this.HandleResult);
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 4cc408e158eec46b28b93a44fc8819ff
timeCreated: 1447720427
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,45 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
* copy, modify, and distribute this software in source code or binary form for use
* in connection with the web services and APIs provided by Facebook.
*
* As with any software that integrates with the Facebook platform, your use of
* this software is subject to the Facebook Developer Principles and Policies
* [http://developers.facebook.com/policy/]. This copyright notice shall be
* included in all copies or substantial portions of the software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Facebook.Unity.Example
{
using System.Collections.Generic;
internal class AppEvents : MenuBase
{
protected override void GetGui()
{
if (this.Button("Log FB App Event"))
{
this.Status = "Logged FB.AppEvent";
FB.LogAppEvent(
AppEventName.UnlockedAchievement,
null,
new Dictionary<string, object>()
{
{ AppEventParameterName.Description, "Clicked 'Log AppEvent' button" }
});
LogView.AddLog(
"You may see results showing up at https://www.facebook.com/analytics/"
+ FB.AppId);
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: e3c0dd81ff77c4c30834810815c69f6d
timeCreated: 1435018470
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,38 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
* copy, modify, and distribute this software in source code or binary form for use
* in connection with the web services and APIs provided by Facebook.
*
* As with any software that integrates with the Facebook platform, your use of
* this software is subject to the Facebook Developer Principles and Policies
* [http://developers.facebook.com/policy/]. This copyright notice shall be
* included in all copies or substantial portions of the software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Facebook.Unity.Example
{
internal class AppLinks : MenuBase
{
protected override void GetGui()
{
if (this.Button("Get App Link"))
{
FB.GetAppLink(this.HandleResult);
}
if (Constants.IsMobile && this.Button("Fetch Deferred App Link"))
{
FB.Mobile.FetchDeferredAppLinkData(this.HandleResult);
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f9f0b7257fa054227be6e26bf1f6b339
timeCreated: 1435164891
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,143 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
* copy, modify, and distribute this software in source code or binary form for use
* in connection with the web services and APIs provided by Facebook.
*
* As with any software that integrates with the Facebook platform, your use of
* this software is subject to the Facebook Developer Principles and Policies
* [http://developers.facebook.com/policy/]. This copyright notice shall be
* included in all copies or substantial portions of the software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Facebook.Unity.Example
{
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
internal class AppRequests : MenuBase
{
private string requestMessage = string.Empty;
private string requestTo = string.Empty;
private string requestFilter = string.Empty;
private string requestExcludes = string.Empty;
private string requestMax = string.Empty;
private string requestData = string.Empty;
private string requestTitle = string.Empty;
private string requestObjectID = string.Empty;
private int selectedAction = 0;
private string[] actionTypeStrings =
{
"NONE",
OGActionType.SEND.ToString(),
OGActionType.ASKFOR.ToString(),
OGActionType.TURN.ToString()
};
protected override void GetGui()
{
if (this.Button("Select - Filter None"))
{
FB.AppRequest("Test Message", callback: this.HandleResult);
}
if (this.Button("Select - Filter app_users"))
{
List<object> filter = new List<object>() { "app_users" };
// workaround for mono failing with named parameters
FB.AppRequest("Test Message", null, filter, null, 0, string.Empty, string.Empty, this.HandleResult);
}
if (this.Button("Select - Filter app_non_users"))
{
List<object> filter = new List<object>() { "app_non_users" };
FB.AppRequest("Test Message", null, filter, null, 0, string.Empty, string.Empty, this.HandleResult);
}
// Custom options
this.LabelAndTextField("Message: ", ref this.requestMessage);
this.LabelAndTextField("To (optional): ", ref this.requestTo);
this.LabelAndTextField("Filter (optional): ", ref this.requestFilter);
this.LabelAndTextField("Exclude Ids (optional): ", ref this.requestExcludes);
this.LabelAndTextField("Filters: ", ref this.requestExcludes);
this.LabelAndTextField("Max Recipients (optional): ", ref this.requestMax);
this.LabelAndTextField("Data (optional): ", ref this.requestData);
this.LabelAndTextField("Title (optional): ", ref this.requestTitle);
GUILayout.BeginHorizontal();
GUILayout.Label(
"Request Action (optional): ",
this.LabelStyle,
GUILayout.MaxWidth(200 * this.ScaleFactor));
this.selectedAction = GUILayout.Toolbar(
this.selectedAction,
this.actionTypeStrings,
this.ButtonStyle,
GUILayout.MinHeight(ConsoleBase.ButtonHeight * this.ScaleFactor),
GUILayout.MaxWidth(ConsoleBase.MainWindowWidth - 150));
GUILayout.EndHorizontal();
this.LabelAndTextField("Request Object ID (optional): ", ref this.requestObjectID);
if (this.Button("Custom App Request"))
{
OGActionType? action = this.GetSelectedOGActionType();
if (action != null)
{
FB.AppRequest(
this.requestMessage,
action.Value,
this.requestObjectID,
string.IsNullOrEmpty(this.requestTo) ? null : this.requestTo.Split(','),
this.requestData,
this.requestTitle,
this.HandleResult);
}
else
{
FB.AppRequest(
this.requestMessage,
string.IsNullOrEmpty(this.requestTo) ? null : this.requestTo.Split(','),
string.IsNullOrEmpty(this.requestFilter) ? null : this.requestFilter.Split(',').OfType<object>().ToList(),
string.IsNullOrEmpty(this.requestExcludes) ? null : this.requestExcludes.Split(','),
string.IsNullOrEmpty(this.requestMax) ? 0 : int.Parse(this.requestMax),
this.requestData,
this.requestTitle,
this.HandleResult);
}
}
}
private OGActionType? GetSelectedOGActionType()
{
string actionString = this.actionTypeStrings[this.selectedAction];
if (actionString == OGActionType.SEND.ToString())
{
return OGActionType.SEND;
}
else if (actionString == OGActionType.ASKFOR.ToString())
{
return OGActionType.ASKFOR;
}
else if (actionString == OGActionType.TURN.ToString())
{
return OGActionType.TURN;
}
else
{
return null;
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 3b4c675f81a254b87adc8ad01006c580
timeCreated: 1435018470
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,125 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
* copy, modify, and distribute this software in source code or binary form for use
* in connection with the web services and APIs provided by Facebook.
*
* As with any software that integrates with the Facebook platform, your use of
* this software is subject to the Facebook Developer Principles and Policies
* [http://developers.facebook.com/policy/]. This copyright notice shall be
* included in all copies or substantial portions of the software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Facebook.Unity.Example
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
internal class DialogShare : MenuBase
{
// Custom Share Link
private string shareLink = "https://developers.facebook.com/";
private string shareTitle = "Link Title";
private string shareDescription = "Link Description";
private string shareImage = "http://i.imgur.com/j4M7vCO.jpg";
// Custom Feed Share
private string feedTo = string.Empty;
private string feedLink = "https://developers.facebook.com/";
private string feedTitle = "Test Title";
private string feedCaption = "Test Caption";
private string feedDescription = "Test Description";
private string feedImage = "http://i.imgur.com/zkYlB.jpg";
private string feedMediaSource = string.Empty;
protected override bool ShowDialogModeSelector()
{
#if !UNITY_EDITOR && (UNITY_IOS || UNITY_ANDROID)
return true;
#else
return false;
#endif
}
protected override void GetGui()
{
bool enabled = GUI.enabled;
if (this.Button("Share - Link"))
{
FB.ShareLink(new Uri("https://developers.facebook.com/"), callback: this.HandleResult);
}
// Note: Web dialog doesn't support photo urls.
if (this.Button("Share - Link Photo"))
{
FB.ShareLink(
new Uri("https://developers.facebook.com/"),
"Link Share",
"Look I'm sharing a link",
new Uri("http://i.imgur.com/j4M7vCO.jpg"),
callback: this.HandleResult);
}
this.LabelAndTextField("Link", ref this.shareLink);
this.LabelAndTextField("Title", ref this.shareTitle);
this.LabelAndTextField("Description", ref this.shareDescription);
this.LabelAndTextField("Image", ref this.shareImage);
if (this.Button("Share - Custom"))
{
FB.ShareLink(
new Uri(this.shareLink),
this.shareTitle,
this.shareDescription,
new Uri(this.shareImage),
this.HandleResult);
}
GUI.enabled = enabled && (!Constants.IsEditor || (Constants.IsEditor && FB.IsLoggedIn));
if (this.Button("Feed Share - No To"))
{
FB.FeedShare(
string.Empty,
new Uri("https://developers.facebook.com/"),
"Test Title",
"Test caption",
"Test Description",
new Uri("http://i.imgur.com/zkYlB.jpg"),
string.Empty,
this.HandleResult);
}
this.LabelAndTextField("To", ref this.feedTo);
this.LabelAndTextField("Link", ref this.feedLink);
this.LabelAndTextField("Title", ref this.feedTitle);
this.LabelAndTextField("Caption", ref this.feedCaption);
this.LabelAndTextField("Description", ref this.feedDescription);
this.LabelAndTextField("Image", ref this.feedImage);
this.LabelAndTextField("Media Source", ref this.feedMediaSource);
if (this.Button("Feed Share - Custom"))
{
FB.FeedShare(
this.feedTo,
string.IsNullOrEmpty(this.feedLink) ? null : new Uri(this.feedLink),
this.feedTitle,
this.feedCaption,
this.feedDescription,
string.IsNullOrEmpty(this.feedImage) ? null : new Uri(this.feedImage),
this.feedMediaSource,
this.HandleResult);
}
GUI.enabled = enabled;
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: e93c4155902d3496399630ee494eab6b
timeCreated: 1435018470
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
Loaded 100 of 1349 files, more files were not shown because too many files have changed in this diff. Show more